MySql 数据库——后端
MySql是开源的,所以你不需要支付额外的费用。
MySql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
可以存储文本数据!
不属于PHP程序,而是与PHP配合的一个软件,是PHP程序中,数据存储的来源!例如数组中调用文章,那么可以把文章存储到数据库,再用PHP去访问数据库,获取到文章,然后再展示到HTML中!
比如要在HTML中发布一篇文章,不可能让文章文本嵌入到HTML中,这样用户看文章,就要下载带有文章文本的HTML,如果文章字数多,全部下载到本地中,有点不方便,编程也不方便呀!
这个时候,就可以把文章存储到数据库,通过PHP代码,去动态调取文章!
一、MySql 基础知识 1、为什么要使用 MySql 2、MySql 介绍
MySQL是(关系型数据库管理系统)的应用软件之一
数据以表格的形式出现
每行:各种记录名称
每列:记录名称所对应的数据域
许多的行和列组成一张表单
若干的表单组成database
3、MySql 环境 像宝塔、xampp、phpstudy等都集成了环境!
4、数据库管理软件
命令行管理数据库
phpMyAdmin 网页管理数据库
Navicat for MySql 软件管理数据库
采用XAMPP的集成的网页来管理!http://localhost/phpmyadmin/
5、MySql 创建库
新建数据库-数据库名-字符集:utf8mb4
6、RDBMS 术语-关系型数据库!
数据库: 数据库是一些关联表的集合。
数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
列: 一列(数据元素) 包含了相同的数据, 例如邮政编码的数据。
行:一行(=元组,或记录)是一组相关的数据,例如一条文章的数据
二、MySql 数据类型 1、数值数据类型
类型
用途
范围(无符号)
范围(有符号)
tinyint
极小整数类型
(0,255)
(-128,127)
smallint
小整数类型
(0,65535)
(-32768,32767)
mediumint
中整数类型
(0,16777215)
(-8388608,8388607)
int
大整数类型
(0,4294967295)
(-2147483648,2147483647)
bigint
极大整数类型
(0,18446744073709551615)
均分成正负
float
浮点小数类型(单精度)
0,约1.17前面38个0,3.4后面38个零
双倍
double
浮点小数类型(双精度)
0,约2.22前308个0,1.79后面308个零
双倍
decimal
定点小数类型
依赖于M和D的值
依赖于M和D的值
注意:数值分为整数和小数,常用tinyint、int、double
decimal定点小数类型:可以规定小数点左边有几位,右边有几位!
2、字符串数据类型
类型
用途
大小(字节)
char
定长字符串
0-255
varchar
变长字符串
0-65535
tinytext
短文本字符串
0-255
text
长文本数据
0-65535
mediumtext
中等长度文本数据
0-16777215
longtext
极大文本数据
0-4294967295
tinyblob
不超过 255 个字符的二进制字符串
0-255
blob
二进制形式的长文本数据
0-65535
mediumblob
二进制形式的中等长度文本数据
0-16777215
longblob
二进制形式的极大文本数据
0-4294967295
注意:保存图片时,是保存地址!常用数据类型:varchar和text
3、日期/时间数据类型
类型
用途
大小(字节)
格式
year
年
3
YYYY
data
日期
3
YYYY-MM-DD
time
时间
3
HH:MM:SS
datatime
日期时间
8
YYYY-MM-DD HH:MM:SS
timestamp
时间戳
4
YYYYMMDD HHMMSS
三、MySql 数据表 1、创建数据表
2、MySql 语句
3、手动添加数据 真实项目中,不允许手动添加数据的!
四、PHP 操作 MySQL 使用php编程,来操作数据库!
一、MySql 语句 1、查询语句
二、PDO 操作数据库 1. 什么是 PDO
PDO: (Php Data Object) php数据对象
PDO 统一了PHP访问各种类型数据库的访问方式
一句话, 不管什么类型数据库, PDO一招搞定
2. PDO 连接
<?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' ,'root' ,'123456' ); $stmt = $pdo ->prepare ('SELECT * FROM article' ); $stmt ->execute (); $arr = $stmt ->fetchAll (); var_dump ($arr ); ?>
3. 编码 header ('content-type:text/html;charset=utf-8' );$pdo = new PDO ('mysql:host=localhost;dbname=boke' , 'root' , 'root' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" ));$pdo ->query ('SET NAMES utf8' );
4、php 复合数据类型
修改完数据库账户密码,不能通过网页访问 解决办法:找到数据库的配置文件,添加刚才更改的密码!
通过记事本或vscode打开文件:C:\xampp\phpMyAdmin\config.inc.php
找到$cfg['Servers'][$i]['password'] = '';添加上刚才更改的密码即可!
尝试连接云服务器上的数据库,结果显示错误!无法访问,并且发现我的服务器数据库没有开启SSL传输!
案例:网页前端文件——通过PHP连接数据库 1、在数据库添加文章数据表 分析:操作数据库,在Mysql软件中,使用SQL语法,在数据库中执行下面代码!注意可以自定义表的名称
CREATE TABLE `article2` ( `title` varchar (300 ) CHARACTER SET utf8 DEFAULT NULL COMMENT '标题' , `img` varchar (300 ) CHARACTER SET utf8 DEFAULT NULL COMMENT '图片' , `content` text CHARACTER SET utf8 COMMENT '内容' , `date ` date DEFAULT NULL COMMENT '时间' , `class` varchar (50 ) CHARACTER SET utf8 DEFAULT NULL COMMENT '类型' ) ENGINE= InnoDB DEFAULT CHARSET= sjis; INSERT INTO `article2` VALUES ('php中文网原创视频:《天龙八部》公益php培训系列课程汇总!' , 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg' , 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!' , '2021-02-18' , 'PHP' );INSERT INTO `article2` VALUES ('php中文网《玉女心经》公益PHP WEB培训系列课程汇总' , 'https://img.php.cn/upload/course/000/126/153/5aa23f0ded921649.jpg' , 'php中文网近期推出的《独孤九贱》系列、《天龙八部》系列、《玉女心经》原创视频课程,好评如潮!由于《玉女心经》系列课程没有做成专题,所以大家找起来有点费劲,为了更好的服务广大php中文网粉丝们,特把课程整理汇总给大家!' , '2021-02-11' , 'PHP' );INSERT INTO `article2` VALUES ('html5中submit是按钮么' , null , 'html5中submit是按钮,它是button的一个特例,它把提交这个动作自动集成了。submit会自动将表单的数据提交,使用submit时需要验证要加return' , '2021-02-10' , '前端' );INSERT INTO `article2` VALUES ('css如何去除下划线' , null , 'css去除下划线的方法:首先创建一个HTML示例文件;然后在body中定义一个a标签;最后通过css属性为“a{text-decoration:none}”去除下划线即可。' , '2021-02-01' , '前端' );INSERT INTO `article2` VALUES ('linux如何查看进程' , 'https://img.php.cn/upload/article/202102/24/2021022409272725770.jpg' , 'windows defender是windows系统自带的一款杀毒软件,对于很多人来说,这款软件不仅没有起到保护电脑的作用,还增加了很多不必要的麻烦。比如我们安装了一些破解版软件,windows defender就会杀这些破解软件,很让人讨厌。' , '2021-02-01' , '服务器' );INSERT INTO `article2` VALUES ('Ubuntu20.04/18.04下安装或更新至PHP8' , 'https://img.php.cn/upload/article/000/000/020/2c02ff679ec7afab974a691aac09d535-0.png' , '本指南让你了解如何安装最新的 php 版本 8,并在你的任何 VPS、云服务器、专用主机上的 Ubuntu 20.0 或 18.04 系统中升级到最新版本,并将其配置为 Apache 和 Nginx。' , '2021-02-01' , 'PHP' );INSERT INTO `article2` VALUES ('PHP 8新特性之JIT对PHP应用性能的影响' , null , '即将发布的 PHP 8 最受大家关注的新特性就是引入了对 JIT 的支持,我已经简单介绍了 JIT 是什么,以及与 Opcache 的区别' , '2021-02-01' , 'PHP' );
2、连接数据库 前端文件中,用户访问网址时,PHP文件解析生成HTML文件,在这个过程中,PHP文件连接到数据库,从数据库获取信息!客户端网页文件一直连接着数据库!数据库崩了,那么网页也会崩了!
<?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); ?>
注意:这个dbname,相当于连接到哪个数据库!
3、获取文章列表 注意:名字要和刚刚新建的数据列表名一致!
<?php $stmt = $pdo->prepare('SELECT * FROM article2'); $stmt->execute(); $lists = $stmt->fetchAll(); ?>
注意:一旦连接成功,相当于表格中的数据可以通过数组$lists
这样就可以把之前手动书写的数据删除了!连接数据库后,获取的文章列表等价于下图信息!并用数组操作去打印数据内容!
<?php $lists = [[ 'title' => 'php中文网原创视频:《天龙八部》公益php培训系列课程汇总!' ,'img' => 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg' ,'content' => 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!' ,'data' => '2021-02-18' ,'class' => 'PHP' ], [ 'title' => 'php中文网原创视频:《天龙八部》公益php培训系列课程汇总!' ,'content' => 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!' ,'data' => '2021-02-18' ,'class' => 'PHP' ], [ 'title' => 'php中文网原创视频:《天龙八部》公益php培训系列课程汇总!' ,'img' => 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg' ,'data' => '2021-02-18' ,'class' => 'PHP' ], [ 'title' => 'php中文网原创视频:《天龙八部》公益php培训系列课程汇总!' ,'img' => 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg' ,'content' => 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!' ,'data' => '2021-02-18' ,], ] ?>
等价于
<?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $stmt = $pdo ->prepare ('SELECT * FROM article2' ); $stmt ->execute (); $lists = $stmt ->fetchAll (); ?>
修改打印列表的代码!访问数据库得到一个二维数组!
<?php foreach ($lists as $lists_v ){ ?> <article> <header class ="entry -header "> <h1 class ="entry -title "> <a href ="/details .html " title ="<?php if (isset ($lists_v ['title '])) { echo $lists_v ['title' ]; } ?> " rel=" bookmark"> //注意,这里使用内层数组,且键名是'title',下面同理 <?php if(isset($lists_v ['title'])){ echo $lists_v ['title']; } ?> </a> </h1> </header> <div class=" entry-content"> <?php if(!empty($lists_v ['content'])){ echo $lists_v ['content']; } ?> </div> <img src=" <?php if (isset ($lists_v ['img' ])){ echo $lists_v ['img' ]; } ?> " alt=" 这是张图片"> <footer class=" entry-meta"> 发布于 <a href=" /index.html?time=2020 -10 -02 " title=" 2020 -10 -02 " rel=" bookmark"> <time class=" entry-date" datetime=" 2020 -10 -02 "> <?php if(isset($lists_v ['data'])){ echo $lists_v ['data']; } ?> </time> </a>。 属于 <a href=" /index.html?cate=4 " title=" 查看 Linux中的全部文章" rel=" category"> <?php if(isset($lists_v ['class'])){ echo $lists_v ['class']; } ?> </a> 分类 </footer> </article> <?php } ?>
注意:这个列表赋值给数组变量$lists,内层数组名$lists_v,再使用键名指定数据!
4、创建分类表
5、分类数据表 CREATE TABLE `class ` ( `name ` varchar (50) DEFAULT NULL COMMENT '分类名' ) ENGINE =InnoDB DEFAULT CHARSET =utf8 ; INSERT INTO `class ` VALUES ('Layui ');INSERT INTO `class ` VALUES ('PHP ');INSERT INTO `class ` VALUES ('ThinkPHP ');INSERT INTO `class ` VALUES ('前端');INSERT INTO `class ` VALUES ('小程序');INSERT INTO `class ` VALUES ('服务器');INSERT INTO `class ` VALUES ('首页');
注意:注意数组名和键!数组名是class,键名是name
6、获取分类列表 <?php $stmt = $pdo ->prepare ('SELECT * FROM class' ); $stmt ->execute (); $menu = $stmt ->fetchAll (); ?>
注意:这里把此列表调取后,创建的数组名是$menu,键名是name
调取和使用代码如下
<?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $stmt = $pdo ->prepare ('SELECT * FROM class' ); $stmt ->execute (); $menu = $stmt ->fetchAll (); ?> <?php foreach ($menu as $val ){ ?> <li> <a href='/index.html' ><?php echo $val ['name' ] ?> </a> </li> <?php } ?>
注意,在创建列表时,数据顺序不同,所以这里调用列表时,显示的顺序不对,怎么解决数据的顺序问题?
五、MySql 增删查改——SQL语法!
关键词
描述
SELECT
查询
INSERT
添加
UPDSTE
修改
DELETE
删除
1、MySql 查询 获取列表内容时使用!
- WHERE 条件 SELECT * FROM article WHERE `class ` = 'PHP ';
查询语句可以增加查询条件,WHERE 条件可以指定一条或多条语句!只查询分类为PHP的!
- 返回值 SELECT title,img,date,class FROM article WHERE `class ` = 'PHP ';
查询语句默认返回值是全部字段,可以指定字段返回!把*替换成字段名,多个字段用逗号隔开!
- LIMIT 分页 SELECT title,img,date,class FROM article WHERE `class ` = 'PHP ' LIMIT 2; SELECT title ,img ,date ,class FROM article WHERE `class ` = 'PHP ' LIMIT 0,2;
查询语句默认把全部符合规定的数据都查询到,任务量很大时会卡死,使用分页,指定需要几条结果!
注意:有两种写法,指定前一个数,就是从第几条数据开始!后几个数据是显示几个查询结果!
- ORDER BY 排序语句
SELECT * FROM article WHERE `class ` = 'PHP ' ORDER BY `date ` DESC ;
查询的结果是以正序显示,还是以倒叙显示,给列表增加排序字段,就可以排序了!日期也可以!
2、MySql 插入 发布文章、注册账号时使用!
INSERT INTO article (`title`,`img`,`content`,`date`,`class `)VALUES ('PHP是很好的编程语言' ,'' ,'PHP是很好的编程语言' ,'2021-03-03' ,'PHP' );
注意:表名括号的字段,依次列出来,并且要和VALUES括号内的数据,一一对应!
3、MySql 修改 UPDATE article SET `title`='PHP中文网' , `content`='PHP中文网' WHERE `title`='PHP是很好的编程语言' ;
注意:SET里面设置要修改的数据,WHERE去指定哪一条要修改,与查询语句语法一致!
一定要指名修改哪一条数据,不然会修改整个表!
4、MySql 删除 DELETE FROM article WHERE `title`='PHP中文网' ;
注意:必须增加条件,不然会删除整个表!
关于条件关键字的使用范围:
关键词
描述
WHERE
条件(查询、修改、删除)
LIMIT
分页(查询)返回的值
ORDER BY
排序(查询)返回的值
不增加条件,到时候删库,只能跑路了!
六、PHP 超全局变量——获取前端表单数据
超级全局变量在PHP 4.1.0之后被启用, 是PHP系统中自带的变量,在一个脚本的全部作用域中都可用!
1、全局变量
变量
描述
$_GET
收集来自 method="get" 的表单中的值
$_POST
收集来自 method="post" 的表单中的值
$_REQUEST
包含 $_POST、$_GET 和 $_COOKIE
$GLOBALS
全部变量的全局组合数组
$_COOKIE
常用于识别用户
$_SESSION
存储关于用户会话(session)的信息
$_FILES
用来获取通过 POST 方法上传文件的相关信息
$_SERVER
服务器和执行环境信息
$_ENV
环境变量
注意:$_GET和$_POST是收集,来自HTML提交的表单!$_REQUEST在php5.3后,默认不开启$_COOKIE
2、$_GET <html > <head > <meta charset ="utf-8" > <title > PHP中文网</title > </head > <body > <form action ="" method ="get" > 讲师: <input type ="text" name ="name" > 学校: <input type ="text" name ="school" > <input type ="submit" value ="提交" > </form > </body > </html > <?php if(!empty($_GET)){ print_r($_GET); } ?>
如果只想打印某条数据,可以通过数组键的方式来打印!
<?php if (!empty ($_GET ['name' ])){ print_r ($_GET ['name' ]); } ?>
注意:$_GET接受的是URL上的值,直接修改浏览器上的URL也可以改变获取的$_GET值!也就是?后面的数据!
get提交时,所有的变量名和值都会显示在 URL 中。所以在发送密码或其他敏感信息时,不要使用这个方法!
方便在浏览器收藏夹收藏
3、$_POST <html > <head > <meta charset ="utf-8" > <title > PHP中文网</title > </head > <body > <form action ="" method ="post" > 讲师: <input type ="text" name ="name" > 学校: <input type ="text" name ="school" > <input type ="submit" value ="提交" > </form > </body > </html > <?php if(!empty($_POST)){ print_r($_POST); } ?>
注意:post提交的信息,不会显示在浏览器的URL中,适合秘密信息,适合大文件!在JS中AJAX也可以提交!
4、$_REQUEST <html > <head > <meta charset ="utf-8" > <title > PHP中文网</title > </head > <body > <form action ="" method ="post" > 讲师: <input type ="text" name ="name" > 学校: <input type ="text" name ="school" > <input type ="submit" value ="提交" > </form > </body > </html > <?php if(!empty($_REQUEST)){ print_r($_REQUEST); } ?>
5、GLOBALS <html > <head > <meta charset ="utf-8" > <title > PHP中文网</title > </head > <body > <form action ="" method ="post" > 讲师: <input type ="text" name ="name" > 学校: <input type ="text" name ="school" > <input type ="submit" value ="提交" > </form > </body > </html > <?php $miejie = '灭绝师太'; print_r($GLOBALS); ?>
显示提交的全部数据,包括GLOBALS本身!包括普通变量!当写完代码,调试代码时,想看用了多少变量,就可以使用这个语句!
二、数据分析——数据的调用与排序 传值(URL最好唯一)、筛选(拿传入的值作为筛选条件)、打印(拿到的数组)三步 案例1:点击文章标题,跳转到详情页!——核心是【传值】 分析:首页文件index.php中文章标题,链接到详情页details.php文件!相当于下载了个静态页面!
问:可不可以跳转到详情页时,在详情页下,动态生成文章标题和内容!
答:可以,详情页也连接数据库,并且在跳转时,增加$_GET传值,并筛选出是哪一篇文章,即根据提交的信息,到数据库找到对应的文章!
方法一:文本传值——URL中传入当前文章标题! 文本传值 <a href ="/details.php?title=URL跳转" > URL跳转</a >
注意:在跳转连接中添加信息,说明哪一篇文章(?后跟的信息),然后使用`$_GET,成为数据库筛选条件!
<h1 class ="entry -title "> //完整代码如下,点击标题,跳转到详情页,传入的是文章标题! <a href ="/details .php ?title =<?php echo $lists_v ['title '] ?>"> //标题的内容 <?php if (isset ($lists_v ['title '])) { echo $lists_v ['title' ]; } ?> </a> </h1>
注意:URL附加一段?信息,可以通过全局变量$_GET获取,作为连接数据库后,筛选文章的条件!
然后到文章详情页,展示文章内容!仅展示当前文章的内容!
<!-- 连接数据库,获取信息 --> <?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $stmt = $pdo ->prepare ('SELECT * FROM article WHERE `title` = "' .$_GET ['title' ].'"' ); $stmt ->execute (); $lists = $stmt ->fetchAll (); $find = $lists [0 ]; ?> <article> <header class ="entry -header "> <h1 class ="entry -title "> <?php echo $find ['title ']; ?> </h1 > </header > <img src ="<?php echo $find ['img ']; ?>" alt ="这里是图片"> <div class ="entry -content ql -editor " id ="md -editor " style ="padding : 0;"> <?php echo $find ['content ']; ?> </div >
注意:这里筛选文章用get传值,用WHERE条件筛选文章名,但是如果两个文章重名怎么办! 接下来用主键,来唯一分辨文章!
方法2:主键传值——URL中传入当前文章主键! 步骤一、创建主键 主键
RDBMS术语:主键是唯一的,一个数据表中只能包含一个主键,你可以使用主键来查询数据。
ALTER TABLE `article` ADD COLUMN `id` int (10 ) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '文章主键' FIRST , ADD PRIMARY KEY (`id`);
在MySQL中,执行命令,给每篇文章,创建唯一主键!
步骤二、主键传值 <a href ="/details.php?id=1" > URL跳转</a >
刚才是用$_GET请求文章名,现在是传入主键!通过主键筛选数据库中唯一文章!
<a href="/details.php?id=<?php echo $lists_v ['id'] ?>" > $stmt = $pdo ->prepare ('SELECT * FROM article2 WHERE `id` = "' .$_GET ['id' ].'"' );
步骤三、打印值,由于筛选,得到的文章一致,这里就不用更改打印了!
案例2:文章分类排序! 给分类创建主键!此时可以正序或者逆序排列!
ALTER TABLE `class ` ADD COLUMN `id ` int (10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' FIRST ,ADD PRIMARY KEY (`id `);
同理:在分类表中,添加主键 问题:如何修改排序!
案例3、通过自定义值排序! 第一步:在数据库中创建排序字段,默认值为0
ALTER TABLE `class ` ADD COLUMN `sort ` int (10) UNSIGNED NULL DEFAULT 0 COMMENT '排序' AFTER `name `;
第二步:给排序字段赋值
第三步:在index.php文件中,修改数据库命令筛选顺序!排序为倒序
$stmt = $pdo ->prepare ('SELECT * FROM class ORDER BY `sort` DESC' );
这样生成的数组,按自定义顺序排列,直接打印输出即可!
案例4、点击分类,仅显示对应分类文章——核心【筛选】 分析:正常是显示全部文章,这里显示的文章为分类文章,也就是说,通过筛选,生成只有当前分类文章!
也就是说,分类与 分类下的文章 创建强联系,且简单、且传人的值强相关!
解决方法,把分类下的文章,都添加上分类对应的主键!
第一步:给文章修改一下分类的值,从分类的文本改为分类的主键!
ALTER TABLE `article` ADD COLUMN `class_id` int (10 ) UNSIGNED NULL DEFAULT 0 COMMENT '分类ID' AFTER `date`;
第二步:传值,修改index.php文件中的文章表链接,添加附加信息!分类主键
<a href='/index.php?id=<?php echo $val[' id'] ?>' >
第三步:筛选文章,添加筛选条件为传入的分类主键
<?php if (!empty ($_GET ['id' ])){ $stmt = $pdo ->prepare ('SELECT * FROM article2 WHERE `class_id` = ' .$_GET ['id' ]); if ($_GET ['id' ]==7 ){ $stmt = $pdo ->prepare ('SELECT * FROM article2' ); } }else { $stmt = $pdo ->prepare ('SELECT * FROM article2' ); } $stmt ->execute (); $lists = $stmt ->fetchAll (); ?>
第四步:打印,与原代码一致
案例5、文章页显示分类名字——核心【打印】! 分析:文章数组中,没有分类的名称,只有分类的主键值!
通过获取全部分类,查找与之相关主键,然后打印分类的名称!
方法一:获取全部分类,打印
属于 <a href="/index.html?cate=4" title="查看 Linux中的全部文章" rel="category" > <?php $stmt = $pdo ->prepare ('SELECT * FROM class' ); $stmt ->execute (); $class_v = $stmt ->fetchAll (); $class_num = (int )$lists_v ['class_id' ]; if (!empty ($class_num )){ echo $class_v [$class_num -1 ]['name' ]; } ?> </a> 分类
注意:生成的分类列表是二维数组,索引为0,对应的id为1,打印时,要在外层数组中的索引减1
WHERE条件
比较运算符
符号
描述
=
等号
<>
不等于
>
大于
<
小于
>=
大于等于
<=
小于等于
SELECT * FROM `article` WHERE `id` = 6 ; SELECT * FROM `article` WHERE `id` <> 6 ; SELECT * FROM `article` WHERE `id` > 6 ; SELECT * FROM `article` WHERE `id` < 6 ; SELECT * FROM `article` WHERE `id` >= 6 ; SELECT * FROM `article` WHERE `id` <= 6 ;
逻辑运算符
符号
描述
NOT
逻辑非,取反
AND
逻辑与
OR
逻辑或
XOR
逻辑异或
SELECT * FROM `article` WHERE NOT (`id` = 1 ); SELECT * FROM `article` WHERE `class ` = 2 AND `date ` = '2021-02-01'; # `OR ` 逻辑或 SELECT * FROM `article ` WHERE `class ` = 2 OR `date ` = '2021-02-01';# `XOR ` 逻辑异或 SELECT * FROM `article ` WHERE `id ` = 1 XOR `id ` = 2;SELECT * FROM `article ` WHERE `id ` = 1 XOR `id ` = 1;
比较运算符
符号
描述
BETWEEN
在两值之间
NOT BETWEEN
不在两值之间
IN
在集合中
NOT IN
不在集合中
LIKE
模糊匹配
SELECT * FROM `article` WHERE `id` BETWEEN 1 AND 10 ; SELECT * FROM `article` WHERE `id` NOT BETWEEN 1 AND 5 ; SELECT * FROM `article` WHERE `id` IN (1 ,5 ); SELECT * FROM `article` WHERE `id` NOT IN (1 ,5 ); SELECT * FROM `article` WHERE `title` LIKE '%PHP%' ; SELECT * FROM `article` WHERE `title` LIKE '%PHP_' ;
注意:筛选数据!从数据库中,查找合适数据!
案例6、文章页显示分类名字 方法一:获取全部分类
属于 <!-- 传入值,键为id,值为当前分类下的值,这样就可以调用已编好的通过id获取,文章分类 --> <a href='/index.php?id=<?php echo $lists_v[' class_id'] ?>' title="查看 Linux中的全部文章" rel="category" > <?php $stmt = $pdo ->prepare ('SELECT * FROM class' );$stmt ->execute ();$menu = $stmt ->fetchAll ();$class_name = [];foreach ($menu as $class_value ){ $class_name [ $class_value ['id' ] ] = $class_value ['name' ]; } if (!empty ($lists_v ['class_id' ])){ echo $class_name [$lists_v ['class_id' ]]; } ?> </a> 分类
注意:获取的是二维数组,每组中只有id和name有用,技巧通过遍历内部数组生成一个新数组,利用新数组去打印值!
方法二:方法类似,没有我的好!
$stmt = $pdo ->prepare ('SELECT * FROM class' );$stmt ->execute ();$menu = $stmt ->fetchAll ();$class = [];if (!empty ($menu )){ foreach ($menu as $menu_v ){ $class [$menu_v ['id' ]] = $menu_v ; } } <a href="/index.php?id=<?php echo $article_v ['class']; ?>" ><?php echo $class [$article_v ['class' ]]['name' ]; ?> </a> 分类
最后:给链接URL附加数据,键为id,值为当前分类下的值,调用已编好的,通过id,仅显示对应分类文章!
案例7、首页 不属于分类,在数据库中删除首页,首页单独拿出来
<li> <a href='/index.php'>首页</a> </li>
案例8、搜索功能 可以通过HTML传值,也可以通过JS传值,然后利用之前的通过id筛选文章,这里改为传入的值来筛选文章!
<script type="text/javascript" > $(function ( ){ $("#searchsubmit" ).click (function ( ){ if ($("#s" ).val () != '' ) { location.href = "/index.php?s=" +$("#s" ).val (); } return false ; }); }); </script>
注意:通过JS传值!
<?php if (!empty ($_GET ['id' ])){ $stmt = $pdo ->prepare ('SELECT * FROM article2 WHERE `class_id` = ' .$_GET ['id' ]);}else if (!empty ($_GET ['s' ])){ $stmt = $pdo ->prepare ('SELECT * FROM article2 WHERE `title` LIKE "%' .$_GET ['s' ].'%"' ); } else {$stmt = $pdo ->prepare ('SELECT * FROM article2' ); } $stmt ->execute (); $lists = $stmt ->fetchAll (); $stmt = $pdo ->prepare ('SELECT * FROM class' ); $stmt ->execute (); $class_menu = $stmt ->fetchAll (); $temp = []; foreach ($class_menu as $class_m ){ $temp [ $class_m ['id' ] ] = $class_m ; } ?>
注意:这里以文章标题作为筛选条件,还可以添加内容作为条件,使用模糊搜索!
案例1:登录页面 第一步、创建管理员表
在数据库中执行下面代码,创建一个账户!
CREATE TABLE `admin` ( `id` int (10 ) unsigned NOT NULL AUTO_INCREMENT COMMENT '管理员ID' , `account` varchar (50 ) NOT NULL COMMENT '账号' , `password` char (32 ) NOT NULL COMMENT '密码' , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO admin (`account`,`password`)VALUES ('admin' ,'e10adc3949ba59abbe56e057f20f883e' );
第二步:在登陆页面中接受传值,连接数据库,查看与数据库中账户密码是否匹配!
<?php $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $stmt = $pdo ->prepare ('SELECT * FROM admin WHERE `account` = "' .$_POST ['account' ].'"' ); $stmt ->execute (); $admin = $stmt ->fetchAll (); if (empty ($admin )){ echo '你输入的账号不存在' ; } ?>
最后判断密码是否正确,然后才是跳转页面,完整代码逻辑
<?php if (!empty ($_POST )){ if (empty ($_POST ['account' ])){ echo '<script>window.alert("请输入账号");history.back();</script>' ; return false ; } if (empty ($_POST ['password' ])){ echo '<script>window.alert("请输入密码");history.back();</script>' ; return false ; } $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $stmt = $pdo ->prepare ('SELECT * FROM admin WHERE `account` = "' .$_POST ['account' ].'"' ); $stmt ->execute (); $admin = $stmt ->fetchAll (); if (empty ($admin )){ echo '<script>window.alert("账号不存在");history.back();</script>' ; return false ; } $find = $admin [0 ]; if (md5 ($_POST ['password' ]) != $find ['password' ]){ echo '<script>window.alert("密码不正确");history.back();</script>' ; return false ; } echo '<script>window.alert("登录成功");window.location.href="article.php";</script>' ; return false ; } ?>
超全局变量 可以跨页面访问,可以任意访问!
变量
描述
$_COOKIE
常用于识别用户
$_SESSION
存储关于用户会话(session)的信息
<?php setcookie ('user' ,'admin' ); print_r ($_COOKIE );
注意:设置一个函数,用user获取键,用admin获取值!
第一次执行,只保存数据,第二次打印,才能打印数据!
<?php session_start (); $_SESSION ['user' ] = 'admin' ; print_r ($_SESSION );
注意:session_start();是必须要有的!一旦储存值,就可以跨页面访问!
这两者区别:$_COOKIE存储在浏览器中空间为4K,$_SESSION存在在服务器上!
案例2:登录后台页面中记录用户信息 思路:先在登录页面中,把正确的账户存在在COOKIE中,再到后台管理页面打印值
步骤一:保存账户到COOKIE中
setcookie ('id' ,$find ['id' ]);setcookie ('account' ,$find ['account' ]);
步骤二:判断登录状态
<?php if (!empty ($_COOKIE ['id' ])){ echo '<script>window.location.href="login.php";</script>' ; return false ; } ?>
方法二:判断登录状态
<?php if (empty ($_COOKIE )){ echo '<script>window.alert("请先登录");window.location.href="login.php"; </script>' ; return false ; } ?>
步骤三:打印账号!
<a class="fly-nav-avatar"> <cite class="layui-hide-xs"><?php echo $_COOKIE['account'] ?></cite> </a>
案例3、在后台页面中展示的文章列表 连接数据库,获取文章信息,获取的是数组,遍历数组,按HTML结构打印显示!之前前端显示文章做过
// 连接数据库,获取文章信息 $pdo = new PDO('mysql:host=localhost;dbname=blog', 'root' , '123456' , array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';")); $stmt = $pdo->prepare('SELECT * FROM article2'); $stmt->execute(); $lists = $stmt->fetchAll(); //获取文章的分类名 $stmt = $pdo->prepare('SELECT * FROM class'); $stmt->execute(); $menu = $stmt->fetchAll(); // print_r($menu); $class_name = []; foreach($menu as $class_value){ //利用遍历数组,来获取每一行中,分类的值,并且把键进行更改!匹配文章中的分类值! $class_name[ $class_value['id'] ] = $class_value['name']; }
遍历数组,在结构中打印
<?php foreach($lists as $lists_v){ ?> <tr> <td><?php if(isset($lists_v['title'])){ echo $lists_v['title']; } ?> </td> <td> <?php if(isset($lists_v['date'])){ echo $lists_v['date']; } ?> </td> <td> <?php if(!empty($lists_v['class_id'])){ echo $class_name[$lists_v['class_id']]; } ?> </td> <td> <button type="button" class="layui-btn layui-btn-normal layui-btn-xs"> <i class="layui-icon layui-icon-edit"></i> </button> <button type="button" class="layui-btn layui-btn-danger layui-btn-xs"> <i class="layui-icon layui-icon-delete"></i> </button> </td> </tr> <?php } ?>
案例4、文章分页 整体思路:把文章分成多少页,每一页仅展示设置的多少条数据!循环HTML结构,页面下方显示多少个页数按钮,点击按钮时,按钮对应链接中传值,通过获取值,来展示第几页,默认为第一页
第一步:按钮结构,每一页的按钮,当前页高亮不可点击,其它页传值可以跳转
<div class ="layui-box layui-laypage layui-laypage-default" > <span class ="layui-laypage-curr" > <em class ="layui-laypage-em" > </em > <em > 1</em > </span > <a href ="article.php?p=2" > 2</a > </div >
第二步:接受值,设置初始值,这是当前页数
if (empty ($_GET ['p' ])){ $p = 1 ; }else { $p = $_GET ['p' ]; }
第三步:获取全部文章的数量,设置页数
$stmt = $pdo ->prepare ('select count(*) as count from `article2`' );$stmt ->execute ();$count = $stmt ->fetchAll ();$count = $count [0 ][0 ];
设置页数,也对应有几个页数按钮,我这里使用变量,来设置每页三条文章
$page_num = 3 ;$page = ceil ($count /$page_num );
注意:p是当前页数,count是总条数,page是总页数
第四步:利用循环,来制作文章按钮,通过判断传入的值,来高亮当前按钮
<!-- 分页按钮,展示分页,并跳转分页 --> <div class ="layui -box layui -laypage layui -laypage -default "> <?php //利用for 循环来生成对应多个按钮 for ($i = 1; $i <= $page ; $i ++) { ?> <?php if ($i == $p ){ ?> <span class ="layui -laypage -curr "> <em class ="layui -laypage -em "></em > <em ><?php echo $i ; ?></em > </span > <?php //否则就生成可以点击的按钮,点击此按钮时,传入当前按钮的值! }else { ?> <a href="article.php?p=<?php echo $i ; ?>" ><?php echo $i ; ?> </a> <?php } ?> <?php } ?> </div>
注意:可以把循环想象成赋值多少分,每一份中运用的中间变量,也生成明确的值! 第五步:点击按钮,生成对应页面 解决方法:通过提取文章的筛选,通过LIMIT 分页,来筛选文章,第一个参数是从第一个数据开始,第二个是筛选出几条数据!
$from_begin = $page_num *($p -1 ); $stmt = $pdo ->prepare ('SELECT * FROM `article2` LIMIT ' .$from_begin .",$page_num " );
案例:发布文章 点击发布文章,跳转到新的页面,需要在新页面中判断是否登录,打印用户信息,实现上传文章到服务器,实现上传图片! 第一步:跳转到发布文章的页面
<button type="button" class ="layui -btn " style ="float :right ;" onclick ="add ()"> <i class ="layui -icon layui -icon -addition "></i >添加 </button > //执行事件函数,跳转到发布文章的页面 function add () { window.location.href='/admin/article_add.php' ; }
第二步:判断登录状态、打印用户信息,这些做过!
<?php if (empty ($_COOKIE )){ echo '<script>window.alert("请先登录");window.location.href="login.php";</script>' ; return false ; } ?> <!-- 打印用户信息 --> <a class ="fly -nav -avatar "> <cite class ="layui -hide -xs "><?php echo $_COOKIE ['account '] ?></cite > </a >
第三步:添加文章 步骤一、给页面添加表单,用来上传图片和文章等信息
<form class ="layui -form "> <div class ="layui -form -item "> <label class ="layui -form -label ">文章标题</label > <div class ="layui -input -block "> <input type ="text " class ="layui -input " name ="title " placeholder ="请输入文章标题" /> </div > </div > <div class ="layui -form -item "> <label class ="layui -form -label ">图片</label > <div class ="layui -input -block layui -upload "> <button type ="button " class ="layui -btn " id ="test1 ">上传图片</button > <div class ="layui -upload -list "> <img class ="layui -upload -img " id ="demo1 " style ="width :100px ;" /> <p id ="demoText "></p > </div > </div > </div > <div class ="layui -form -item "> <label class ="layui -form -label ">详情</label > <div class ="layui -input -block "> <textarea class ="layui -textarea " name ="content " placeholder ="请输入详情" ></textarea > </div > </div > <div class ="layui -form -item "> <label class ="layui -form -label ">分类</label > <div class ="layui -input -block "> <select name ="class " lay -verify ="required " lay -search =""> <option value ="">请选择分类</option > <option value ="1">layer </option > </select > </div > </div > </form >
用$_POST变量来获取提交的数据
步骤二、获取到的数组包含标题、内容、分类,分别用三个变量来存储!
if (!empty ($_POST )){ $title = $_POST ['title' ]; if (empty ($title )){ echo '请输入标题' ; exit ; } $content = $_POST ['content' ]; if (empty ($title )){ echo '请输入内容' ; exit ; } $class = $_POST ['class' ]; if (empty ($title )){ echo '请选择分类' ; exit ; } }
步骤三、把获取到的数据插入到数据库中
try { $pdo = new PDO ('mysql:host=localhost;dbname=blog' , 'root' , '123456' , array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';" )); $sql = "INSERT INTO article2 (`title`,`img`,`content`,`date`,`class_id`)VALUES('{$title} ','','{$content} ','{$date} ','{$class} ');" ; $stmt = $pdo ->prepare ($sql ); $stmt ->execute (); echo json_encode (['code' =>0 ,'msg' =>'添加成功' ]); }catch (PDOException $e ){ echo json_encode (['code' =>1 ,'msg' =>'添加失败' ]); } return false ;
上传文章就成功了,接下来解决分类和上传图片!
案例:下拉分类选项 首先是从数据库中获取分类,然后遍历数组,打印分类!
$stmt = $pdo ->prepare ('SELECT * FROM class ORDER BY `sort` DESC' );$stmt ->execute ();$menu = $stmt ->fetchAll ();<?php foreach ($menu as $menu_class ){ ?> <option value="<?php echo $menu_class ['id'] ?>" ><?php echo $menu_class ['name' ] ?> </option> <?php } ?>
案例:上传图片! 步骤一、上传图片的JS代码
layui.use (['layer' ,'form' ,'upload' ],function ( ){ form = layui.form ; layer = layui.layer ; upload = layui.upload ; $ = layui.jquery ; var uploadInst = upload.render ({ elem : '#test1' ,url : 'up_img.php' ,before : function (obj ){ obj.preview (function (index, file, result ){ $('#demo1' ).attr ('src' , result); }); } ,done : function (res ){ if (res.code > 0 ){ layer.msg ('上传失败' ,{'icon' :2 }); }else { layer.msg ('上传成功' ,{'icon' :1 }); } } }); });
步骤二、写接口 !新建个文件夹,取名为upload_img.php,在文件中,赋值下面的代码,使用全局变量上传文件
变量
描述
$_FILES
用来获取通过 POST 方法上传文件的相关信息
<?php print_r ($_FILES ); ?>
upload_tmp_dir = C:\Windows\temp
上传图片显示接口错误,打开调试,发现没有错误,上传的图片信息能看见,图片格式为临时文件
步骤三、创建文件夹,并对改变上传文件的编码格式,把图片从临时文件移到创建的文件夹中
函数
描述
json_encode
对变量进行 JSON 编码
is_dir
检查指定的文件是否是目录
iconv
字符串按要求的字符编码来转换
mkdir
创建目录
move_uploaded_file
将上传的文件移动到新位置
在上传文件upload_img.php下,替换成下面的代码!
<?php if ($_FILES ['file' ]['error' ] > 0 ){ echo json_encode (['code' =>1 ]); }else { if (!is_dir ('upload/' )){ $res = mkdir (iconv ('UTF-8' ,'GBK' ,'upload/' ),0777 ,true ); } move_uploaded_file ($_FILES ['file' ]['tmp_name' ],'upload/' .$_FILES ['file' ]['name' ]); echo json_encode (['code' =>0 ]); } ?>
图片上传成功!但是同一名字的图片,无法上传第二遍!设置上传图片时,自动改名字!
步骤四、更改上传的图片名称
$date = time ();$name = explode ('.' ,$_FILES ['file' ]['name' ]);move_uploaded_file ($_FILES ['file' ]['tmp_name' ],'upload/' .$date .'.' .$name [1 ]);echo json_encode (['code' =>0 ]);
利用时间戳来自动生成名字!
步骤五、增加返回值,在把保存的图片地址返回来,等下上传到数据库中,更改upload_img.php上传文件
<?php if ($_FILES ['file' ]['error' ] > 0 ){ echo json_encode (['code' =>1 ]); }else { if (!is_dir ('upload/' )){ $res = mkdir (iconv ('UTF-8' ,'GBK' ,'upload/' ),0777 ,true ); } $date = time (); $name = explode ('.' ,$_FILES ['file' ]['name' ]); move_uploaded_file ($_FILES ['file' ]['tmp_name' ],'upload/' .$date .'.' .$name [1 ]); echo json_encode (['code' =>0 ,'data' =>'admin/upload/' .$date .'.' .$name [1 ]]); } ?>
把返回值放入到表单中,增加个隐藏表单,注意这里的图片返回的地址是相对地址,再判断上传是否成功!
<div class ="layui -upload -list "> <img class ="layui -upload -img " id ="demo1 " style ="width :100px ;" /> <!-- 增加隐藏`input `框,存储上传后的图片地址 --> <input type ="hidden " class ="layui -input " id ="img " name ="img " /> </div > ,done : function (res ) { if (res.code > 0 ){ layer.msg ('上传失败' ,{'icon' :2 }); }else { $('#img' ).val (res.data); layer.msg ('上传成功' ,{'icon' :1 }); } } $file = 'upload/' .$date .'.' .$name [1 ];move_uploaded_file ($_FILES ['file' ]['tmp_name' ],$file );echo json_encode (['code' =>0 ,'data' =>$file ]);
步骤六、在提交页面中,增加图片的$_POST数据,在SQL语句中,增加{$img}!
$img = $_POST ['img' ];$sql = "INSERT INTO article2 (`title`,`img`,`content`,`date`,`class_id`)VALUES('{$title} ','{$img} ','{$content} ','{$date} ','{$class} ');" ;
数据结构——类与对象
1、创建类 类就相当于,JS的对象,API等,带有方法和对象的模板,可以在此模板上去创建其它对象!
class Teacher {} $ouyang = new Teacher ();
注意:使用关键字——class创建类,使用关键字new创建于类相关的对象!实例化!
2、复合数据类型——对象
var_dump ($ouyang );var_dump ($miejue );var_dump ($ximen );
三个实例化对象!
var_dump ($ouyang == $miejue );echo '<hr/>' ;var_dump ($miejue == $ximen );echo '<hr/>' ;var_dump ($ouyang == $ximen );
注意:三个实例化对象的值相等,但并不全等!
3、成员变量——类属性
成员变量,也叫: 类属性,和JS中对象的属性差不多,不过这个属性有关键字public
class Teacher { public $name = '灭绝师太' ; public $school = 'PHP中文网' ; } $ouyang = new Teacher ();echo $ouyang ->name;echo '<hr/>' ;echo $ouyang ->school;
可以直接访问实例化对象的属性值,$ouyang->name
4、成员方法——方法 class Teacher { public $name = '灭绝师太' ; public $school = 'PHP中文网' ; public function fun1 ( ) { echo '姓名:灭绝师太,学校:PHP中文网<hr/>' ; } public function fun2 ( ) { return '姓名:灭绝师太,学校:PHP中文网<hr/>' ; } public function fun3 ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } public function fun4 ( ) { return $this ->fun3 (); } } $yangmi = new Teacher ();$yangmi ->fun1 ();echo $yangmi ->fun2 ();echo $yangmi ->fun3 ();echo $yangmi ->fun4 ();
注意:方法也要用关键字public创建,方法里面可以使用伪变量this访问内部成员!
魔术方法
方法
描述
__construct
构造方法
__destruct
析构方法
class Teacher { public $name ; public $school ; public function __construct ($name , $school ) { $this ->name = $name ; $this ->school = $school ; } public function fun3 ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } $obj = new Teacher ('西门大官人' ,'PHP中文网' );echo $obj ->fun3 ();
允许在类内,使用关键字__construct,来构造方法!在实例化的时候,立即执行!
class Teacher { public function __destruct ( ) { echo '类执行完毕,要关闭了' ; } }
自动执行,用来释放数据!
方法
描述
__call
在对象中调用一个不可访问方法时调用
__callStatic
用静态方式中调用一个不可访问方法时调用
__get
获得一个类的成员变量时调用
__set
设置一个类的成员变量时调用
__isset
当对不可访问属性调用isset()或empty()时调用
__unset
当对不可访问属性调用unset()时被调用
__sleep
执行serialize()时,先会调用这个函数
__wakeup
执行unserialize()时,先会调用这个函数
__toString
类被当成字符串时的回应方法
__invoke
调用函数的方式调用一个对象时的回应方法
__set_state
调用var_export()导出类时,此静态方法会被调用
__clone
当对象复制完成时调用
__autoload
尝试加载未定义的类
__debugInfo
打印所需调试信息
5、类的三大特性
继承:可以让某个类型的对象获得另一个类型的对象的属性和方法
封装:指将客观事物抽象成类,每个类对自身的数据和方法实行保护
多态:指同一个实体同时具有多种形式,它主要体现在类的继承体系中
1、继承
class PHPTeacher extends Teacher {} $obj = new PHPTeacher ('西门大官人' ,'PHP中文网' );
2、封装
public 默认的, 关键词定义类内、类外、子类都可见
protected 关键词定义类内、子类可见,类外不可见
private 关键词定义类内可见, 子类、类外不可见
class Teacher { protected $name ; private $school ; public function fun7 ( ) { return $this ->name; } public function fun8 ( ) { return $this ->school; } } $obj = new Teacher ('西门大官人' ,'PHP中文网' );echo $obj ->name;echo $obj ->school;echo $obj ->fun7 ();echo $obj ->fun8 ();
用关键字定义变量或者方法的特点!
3、多态
class Teacher { private function fun2 ( ) { return '姓名:灭绝师太,学校:PHP中文网<hr/>' ; } } class PHPTeacher extends Teacher { public function fun2 ( ) { return '我是重写的方法' ; } } $obj2 = new PHPTeacher ('西门大官人' ,'PHP中文网' );echo $obj2 ->fun2 ();
子类,可以重写父类的方法!
6、类进阶 1、静态成员
class Teacher { public static $name ; public static $school ; } Teacher ::$name = '西门大官人' ;echo Teacher ::$name ;
特点:不需要实例化,直接访问和修改内部属性!
2、抽象类
abstract class Teacher { protected $name ; private $school ; public function __construct ($name , $school ) { $this ->name = $name ; $this ->school = $school ; } public function fun3 ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } abstract public function fun4 ( ) ; } class PHPTeacher extends Teacher { public function fun5 ( ) { return $this ->fun3 (); } public function fun4 ( ) { return '我是继承后重写的方法' ; } } $obj2 = new PHPTeacher ('西门大官人' ,'PHP中文网' );echo $obj2 ->fun4 ();echo $obj2 ->fun5 ();
注意:抽象类不能实例化,可以被继承!
3、接口
interface 关键词创建接口。要求类必须实现的方法,但不需要定义方法的具体实现过程
implements 关键词使用接口
interface file { public function noTF ($param ) ; public function noZY ($param ) ; } class Teacher implements file { protected $name ; private $school ; public $noTF ; public $noZY ; public function __construct ($name , $school ) { $this ->name = $name ; $this ->school = $school ; } public function noTF ($param ) { $this ->noTF = $param ; } public function noZY ($param ) { $this ->noZY = $param ; } public function fun1 ( ) { return '我是' .$this ->name.',' .$this ->noTF.$this ->noZY; } } $obj = new Teacher ('欧阳' ,'PHP中文网' );$obj ->noTF ('我没有体罚学生,' );$obj ->noZY ('我没有布置作业。' );echo $obj ->fun1 ();
注意:接口不能写完整函数,也就是不包括代码块!要在implements中对方法说明,才能使用!
4、接口常量
常量是不允许被改变的量,定义就必须赋值,赋值后就无法改变!
5、常量 define ('HOST' ,'127.0.0.1' );echo HOST;echo '<hr/>' ;const NAME = 'PHP中文网' ;echo NAME;
6、关键词
关键词
类外声明
声明类
声明属性
声明方法
解释
const
√
√
定义类常量
extends
√
扩展类,用一个类去扩展它的父类,继承
public
√
√
公用属性或方法
protected
√
√
私有属性或方法
private
√
√
受保护的属性或方法
static
√
√
√
静态成员
abstract
√
√
抽象类或方法
interface
√
创建接口
implements
√
实现接口
final
√
√
类不能被继承
parent::
访问父类
$this->
访问本类
self::
访问本类静态
namespace
√
创建命名空间
final class Teacher { public $name = '西门' ; } class PHPTeacher extends Teacher {} $obj = new PHPTeacher ('西门大官人' ,'PHP中文网' );echo $obj ->name;
class Teacher { public $name ; public $school ; public function __construct ($name , $school ) { $this ->name = $name ; $this ->school = $school ; } public function fun3 ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } } class PHPTeacher extends Teacher { public function fun3 ( ) { return parent ::fun3 (); } } $obj = new PHPTeacher ('西门大官人' ,'PHP中文网' );echo $obj ->fun3 ();
class Teacher { public static $name ; public static $school ; public static $gongfu = 'PHP' ; public static function fun5 ( ) { return '姓名:' .self ::$name .',学校:' .self ::$school .'<hr/>' ; } } echo Teacher ::$gongfu ;Teacher ::$name = '西门大官人' ;Teacher ::$school = 'PHP中文网' ;echo Teacher ::fun5 ();
7、命名空间
命名空间: 解决全局成员的命名冲突问题, 借鉴了文件目录的思想
目录: 同一目录下不允许重名文件, 但不同目录下, 允许同名文件存在
空间: 同一空间内不允许成员重名, 但不同空间内, 允许同名成员存在
1、命名空间
function php ( ) {} function php ( ) {}
这会报错,不能同名,但可以解决!
2、创建命名空间
namespace one { function php (){ } } namespace two { function php (){ } } //或者使用结束符,更倾向于第二种! namespace three ;function php ( ) {} namespace four ;function php ( ) {}
3、常量、函数、类 只能在对应的命名空间能直接使用,跨区域会报错,变量可以跨!
4、子命名空间 namespace { const NAME = '灭绝师太'; function php ( ) { } class phpcn { } } namespace one { const NAME = '西门大官人'; function php ( ) { } class phpcn { } } namespace one \two { const NAME = '西门大官人'; function php ( ) { } class phpcn { } }
5、访问命名空间
use 关键字引用命名空间
AS 解决类名过长、重名问题
namespace one ;const NAME = '灭绝师太的常量' ;function php ( ) { echo '灭绝师太的函数' ; } class phpcn { public function fun ( ) { echo '灭绝师太的类' ; } } echo php ();echo '<hr>' ;echo \two\php ();echo '<hr>' ;echo \one\two\three\php ();echo '<hr>' ;use \one \two \three as t ;echo t\php ();echo '<hr>' ;namespace two ;const NAME = '西门大官人的常量' ;function php ( ) { echo '西门大官人的函数' ; } class phpcn { public function fun ( ) { echo '西门大官人的类' ; } } namespace one \two \three ;const NAME = '欧阳的常量' ;function php ( ) { echo '欧阳的函数' ; } class phpcn { public function fun ( ) { echo '欧阳的类' ; } }
6、冲突——不同文件夹下同一命名空间,引入到同一文件中使用时,发生冲突!
<?php namespace one \one ; const NAME = '灭绝师太的常量' ; function php ( ) { echo '灭绝师太的函数' ; } class phpcn { public function fun ( ) { echo '灭绝师太的类' ; } }
<?php namespace two \one ; const NAME = '西门大官人的常量' ; function php ( ) { echo '西门大官人的函数' ; } class phpcn { public function fun ( ) { echo '西门大官人的类' ; } }
<?php require 'one\one.php' ; require 'two\one.php' ; use one \one as o ; use two \one as t ; $php = new t\phpcn (); $php ->fun (); echo '<hr>' ; echo o\php ();
8、PHP8 类的新特性1、构造器属性提升 <?php namespace phpcn ; class Teacher { public $name ; public $school ; public function __construct ($name , $school ) { $this ->name = $name ; $this ->school = $school ; } public function fun ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } } $obj = new Teacher ('灭绝师太' ,'PHP中文网' ); echo $obj ->fun ();
<?php namespace phpcn ; class Teacher { public function __construct ( public $name , public $school ) { } public function fun ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.'<hr/>' ; } } $obj = new Teacher ('西门大官人' ,'PHP中文网' ); echo $obj ->fun ();
注意:这里允许,直接传参!
2、联合类型
类型
描述
bool
布尔型:true 和 false
int
整型:负数 - 0 - 无限大
float
浮点型:带小数的数字(负数 - 0 - 无限大)
string
字符串:汉字、英文、符号、其它国家语言
array
数组:一组数据的集合
object
对象:存储数据和有关如何处理数据的信息
mixed
新增:任何类型
<?php namespace phpcn ; class Teacher { public function __construct ( public string $name , public string $school , public int |float $num ) { } public function fun ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.',今年是' .$this ->num.'年<hr/>' ; } } $obj = new Teacher ('西门大官人' ,'PHP中文网' ,2022 ); echo $obj ->fun ();
3、mixed
<?php namespace phpcn ; class Teacher { public function __construct ( public mixed $name , public mixed $school , public mixed $num ) { } public function fun ( ) { return '姓名:' .$this ->name.',学校:' .$this ->school.',今年是' .$this ->num.'年<hr/>' ; } } $obj = new Teacher ('西门大官人' ,'PHP中文网' ,2022 ); echo $obj ->fun ();