第三章 PHP基础语法
了解PHP作者
:::tip
PHP之父:拉斯马斯·勒德尔夫 在1994创建PHP,刚刚开始只是一个简单的用Perl语言编写的程序,用来统计他自己网站的访问者。后来又用C语言重新编写,包括可以访问数据库。在1995年以Personal Home Page Tools (PHP Tools) 开始对外发表第一个版本,Lerdorf写了一些介绍此程序的文档,并且发布了PHP1.0。
:::
PHP历史版本
-
1.0 1995-06-08 – 首次使用
-
2.0 1997-11-01 – PHP首个发行版
-
3.0 1998-06-06 2000-10-20 Zeev Suraski和Andi Gutmans重写了底
-
4.0 2000-05-22 2001-06-23 增加了Zend引擎
-
5.0 2004-07-13 2005-09-05 ZendⅡ引擎
- 5.1 2005-11-24 2006-08-24 引入了编译器来提高性能、增加了PDO作为访问数据库的接口
- 5.2 2006-11-02 2011-01-06 默认启用过滤器扩展
- 5.3 2009-06-30 2014-08-14 支持命名空间;使用XMLReader和XMLWriter增强XML支持;支持SOAP ,延迟静态绑定,跳转标签(有限的goto), 闭包,Native PHP archives。
- 5.4 2012-03-01 2015-09-03 支持Trait、简短数组表达式。移除了register_globals, safe_mode, allow_call_time_pass_reference, session_register(), session_unregister(), magic_quotes以及session_is_registered()。加入了内建的Web服务器。增强了性能,减小内存使用量。
- 5.5 2013-06-20 2016-07-10 支持generators,用于异常处理的finally ,将OpCache(基于 Zend Optimizer+)加入官方发布中。
- 5.6 2014-08-28 2018-12-31 常数标量表达式、可变参数函数、参数拆包、新的求幂运算符、函数和常量的use语句的扩展、新的phpdbg调试器作为SAPI模块,以及其他更小的改进
-
6.x 未发布 – 取消掉的、从未正式发布的PHP版本。
-
7.0 2015-12-03 2018-12-03 Zend Engine 3 (性能提升并在Windows上支持 64-bit 整数),统一的变量语法, 基于抽象语法树编译过程。
- 7.1 2016-12-01 2019-12-01 void返回值类型,类常量,可见性修饰符
- 7.2 2017-11-30 2020-11-30 对象参数和返回类型提示、抽象方法重写等
- 7.3 2018-12-06 2021-12-06 PCRE2支持等
- 7.4 2019-11-28 2022-11-28 改进OpenSSL、弱引用等
-
8.0
JIT、数组负索引等
:::tip
截止2022年PHP已经诞生27周年啦,php版本和功能一直在更新发展,PHP 7.4每秒处理的请求数量是PHP 5.6的三倍,比PHP 7.0快约18%;PHP 8.0新特性JIT(即时)编译器,这可能为在Web服务器上进行机器学习,3D渲染和数据分析打开大门,未来无限想象…最后最重要的一点是,根据w3c统计,PHP在网站的服务器端编程语言中所占的份额仍然接近79%,并且没有近一步下降,在这方面,社区可以以健康的自信心行事,无需回避与其他语言的比较。至于每年都会冒出诸如“ PHP有未来吗?”,“仍然值得学习PHP吗?”,“ PHP是否失去重要性?”甚至“ PHP即将消亡”之类的问题,我想再去争执已经没有意义,想学习就从现在开始吧!
::: -
10000
-
15
WEB领域开发语言排行榜
https://w3techs.com/【75%】
PHP入门
掌握标记风格
掌握注释
掌握在PHP脚本中输出内容【HTML CSS JS】
了解HTML嵌入PHP【混编】
PHP数据类型
:::warning
- PHP是弱类型语音
- 变量不需要声明就可以直接赋值,值得类型就是变量类型,声明变量不需要声明类型;
- 声明变量一定是$符号开头;
- 声明变量名称不能以数字开头,也不能是特殊符号开头,可以是_下划线;
- 变量区分大小写
- 变量声明后值得类型可以切换
:::
PHP数据类型(8)种
标量数据类型【是数据结构中最基本单元,只能储存一个数据】
- 整型
- 浮点型
- 布尔值
- 字符串
复合数据类型
- 数组
- 对象
特殊的数据类型
- NULL
- Resource
整型
- 正负数
- 最大值PHP_INT_MAX,最小值PHP_INT_MIN,字节数PHP_INT_SIZE
- 2进制(0b110011)
- 8进制(012307)不能超过7
- 16进制(0x09AF)不能超过F
浮点型
- 小数位
- 精度
- 科学计数法 // 3.14e8
- 不能直接比较
0.1+0.7 和 0.8 比较?
<?php
error_reporting(E_ALL);//设置报错级别
$_port = 80;
$_port ="80";
$_port = true;
$_port = [];
echo PHP_INT_MAX;//PHP内置魔术常量
echo "<br>";
echo '系统位数:'.PHP_INT_SIZE;
$a= 0.1+0.7;
$b = 0.8;
//
if($a === $b){
echo '相等';
}else{
echo 'No相等';
}
$age = 18;
//$age2 = 28;
$username = '$age2<h1 style="color:red"></h1>';
echo '单引号中有变量'.$username;
$username = $age."2<h1 style=\"color:red\"></h1>".$age;
echo '双引号中有变量'.$username;
字符串
- 单引号
- 双引号
- 转义字符
- 单引号双引号区别
- 字符串连接 .
- heredoc结构
<?php
$age = 18;
$style = <<<ABC
<style>
body{
font: 16px arial,'Microsoft Yahei','Hiragino Sans GB',sans-serif;
}
h1{
margin: 0;
color:#3a87ad;
font-size: 26px;
}
.content{
width: 45%;
margin: 0 auto;
}
.content >div{
margin-top: 200px;
padding: 20px;
background: #d9edf7;
border-radius: 12px;
}
.content dl{
color: #2d6a88;
line-height: 40px;
}
.content div div {
padding-bottom: 20px;
text-align:center;
}
</style>
ABC;
$html =<<<YKH
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>400 错误 - phpstudy</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<meta HTTP-EQUIV="pragma" CONTENT="no-cache">
<meta HTTP-EQUIV="Cache-Control" CONTENT="no-store, must-revalidate">
<meta HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
<meta HTTP-EQUIV="expires" CONTENT="0">
{$style}
</head>
<body>
<div class="content">
<div>
<h1>{$age}HTTP 400 - Bad Request</h1>
<dl>
<dt>错误说明:因为错误的语法导致服务器无法理解请求信息。</dt>
<dt>原因1:客户端发起的请求不符合服务器对请求的某些限制,或者请求本身存在一定的错误。</dt>
<dd>解决办法:</dd>
<dd>链接中有特殊字符或者链接长度过长导致,请对应修改.</dd>
<dt>原因2:request header 或者 cookie 过大所引起</dt>
<dd>解决办法:</dd>
<dd>crtl+shift+delete 快捷键清除cookie.</dd>
</dl>
<div>使用手册,视频教程,BUG反馈,官网地址: <a href="https://www.xp.cn" target="_blank">www.xp.cn</a> </div>
</div>
</div>
</body>
</html>
YKH;
echo $html;
布尔值
- 特殊值的布尔值【0,0.0,“”,“0”,“0.0”,NULL,“null”】
数组,对象,NULL,Resource
伪类型【了解,看得到官网函数参数的类型要求即可】
- mixed
- number
- void
- callback
类型转换
自动转换【隐式转换】【逻辑判断时注意或者处理用户数据时注意】
原则:保留更高的精度;
数值转换中遇到非数【0-9】字停止
- 转为布尔值
$int= 1;
$float= 12.12;
$str1 = "123";
$str2 = 1+"abc123";
$str4 = "123abc";
$bool = "0";//0 0.0 "" "0" "0.0" null,"null" 数组越界
1 +"abc123.88"
if($bool){
//
}
强制转换
使用类型函数或者在变量前加括号或者settype
$a = "123hello";
//1
$a = (int)$a; //123
//2
$b = "123hello";
$b = intval($a); //123
//
$c = "123hello";
settype($c,"int"); //123
上周回顾
- 关于PHP变量下列说法正确的是:
- A:PHP变量不区分大小写
- B:PHP变量的名称不能是数字开头
- C:PHP变量声明时需要指明具体的数据类型
- D:PHP是弱类型语言,因此变量声明后其值类型不能被改变
- 关于PHP中字符串说法正确的是:
- A:PHP字符串可以使用单引号或者双引号,二者没有任何区别
- B:一般优先使用单引号声明字符串
- C:字符串中如果存在双引号,一定要使用转义字符\
- D:字符串中如果存在单引号,可以不要使用转义字符\
$a = 1;
$b = "0.68hello";
$c = $a + $b;//
echo $c;//? 1
var_dump($c);//?
--------------------[1]-----------------------
$float = 0.0;
$A = (bool)$float;
echo $A;//?
var_dump($float);
var_dump($A);//?;
------------------[intval() 2]---------------
-------------------[3]------------------------
$float = 0.0;
$A = settype($float,'bool');
echo $A;
var_dump($float);
var_dump($A);
-------------------------------------------
//PHP中标量的数据类型有哪些?
运算规则试题
$a= 0;
$b= 0;
//比较运算符 逻辑运算符 赋值运算符
//短路运算
//$a = true;
//exp1||exp2||exp3 短路
if($a= 3>0 || $b= 3>0){
//$a = true;
$a++;
$b++;
}
echo true;//1
echo false;//'空白'
echo $a,$b;//1 1
/**************/
$a=5;
//先返回5 再自增6
//先自增7 再返回7
//5+7
$b = ($a++) + (++$a);
则$b的值是___________。
$c=5;
$d=6;
$e = ($c==6)&&($d=7);
则,$d的值是__6____
//与运算的短路运算
//PHP
$f = 3||(4>3);
var_dump($f);//bool(true)
//与JS的区别?
var a = 3||(4>1);
//a = 3
PHP错误级别
PHP程序流程控制
条件控制语句
二者都不考虑数值类型,相当于进行了 == 判断
- if…elseif…elseif…else
- switch
$is_handsome = true;//true
$three = false;
//建议不能超过3层嵌套
$is_handsome = 1;
if(){
}elseif(){
}elseif(){
}elseif(){
}else(){
}
switch($is_handsome){
case 3:
//code.....
break;
case '1':
//code1
break;
case '2':
//code2
break;
default:
//code3....
}
$is_handsome = 3;
switch($is_handsome){
case 1:
case 2:
case 3:
//code
break;
default:
//code3....
}
循环控制语句
不要出现死循环
-
while() ;//如果…就
-
do{}while();//不管…
-
for(;😉{}
- 编程求1-100奇数之和
- 编程找出所有水仙花数(三位数,个位、十位、百位三次方之和等于三位数本身)
- 编程输出以下图形
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
- foreach(){}
流程控制符
- break //结束当前循环
- break N 结束第N层循环
- continue //跳出当前循环
- continue N //跳出第N层循环
- return
- 非函数中,结束当前脚本的运行
- 如果在被包含文件的脚本中,则只是结束被包含文件的运行。
- 在函数中,返回值给调用者
- 非函数中,结束当前脚本的运行
- exit //在任何地方都是终止脚本的运行
- 如果在被包含文件的脚本中,都是终止脚本的运行。
含外部文件
使用方法
作用
被包含文件中的任何全局变量,都可以直接使用
被包含文件中的任何函数或者类,都可以调用
通常把公共部分的代码抽离出去作为公共文件被引入使用
PHP函数
- intval() var_dump() error_reporting() settype()
- 优先使用系统函数
变量区分大小写,函数名称不区分大小写,函数可以是自定义函数,也有系统函数
函数的命名
- 按照变量的规则去定义【语义化】
- 函数不区分大小写
函数中的错误
- Fatal error: Uncaught Error: Call to undefined function var_dum()
- 【调用的函数名称错误】代码执行到这里就终止了。
- Fatal error: Uncaught ArgumentCountError: Too few arguments
- 【调用的函数的参数个数不匹配】代码执行到这里就终止了。
函数的参数
参数的默认值
参数的引用传递
函数体中变量的作用域
函数体中的静态变量
function _get_goods(){
static $num = 1;
//整个程序执行的生命周期中第一次调用时进行初始化,函数执行完毕后该变量不会被立即销毁,值会被保存下 来,当程序程序结束后才销毁
//可以充当临时缓存的作用【计算量比较大 多次运算的 可以使用static】
}
函数体中使用全局变量
//1 global $var;//声明
//2 $GLOBALS['var']
函数的返回值
return
函数的调用
return
exit ;//脚本强制结束
递归函数
- 函数调用本身
- 注意1:一定要有临界值【终止调用本身的条件】
- 注意2:注意函数的返回值
function echoNstr($num=10){
if($num == 1){
echo '<==>';//B
}else{
echo $num;//A
echoNstr($num-1);
}
echo $num;//
}
//执行结果 10
10 9 8 7 6 5 4 3 2 <==>1 2 3 4 5 6 7 8 9 10
//计算N阶乘
function fact($num = 10){
if($num ==1){
return 1;//B
}else{
return $num*fact($num-1);//A
}
}
//5
//return 5*24
function fact_2($num = 10){
if($num ==1){
$res = 1;//B
}else{
$res= $num*fact_2($num-1);//A
}
return $res;
}
//5
$res = 5*24
return $res;
P100 把分支语句改为变量函数【4种不同操作调用4个不同函数,由变量函数调用】
变量函数
//可变变量
$num = 'dire';
$jia = 'jian';
$dire = 'left';
$$num ;//left
//可变函数
$call_func_name = 'left';
$call_func_name();
//动态执行某个方法
//有可能是系统函数,安全问题。
function plus(){
}
function left(){
}
function right(){
}
函数试题
$val_1= 5;
$val_2 = 10;
$my_val = 5;
function foo(&$my_val){
global $val_1; //
$val_1 += 2;
$val_2 = 4;
$my_val += 3;
return $val_2;
}
echo foo($my_val); //4
echo $my_val; //8
echo $val_1."<br>".$val_2; //7 10
$bar = 'foo';
$my_val =10;
//变量函数 foo(10);
echo $bar($my_val); //4
常量
大写字母和下划线
脚本执行的生命周期中值不变也不能变
全局范围的作用域【函数内部,对象内部】
预定义常量
PHP_OS //当前的操作系统
PHP_VERSION //当前脚本执行的PHP版本号
DIRECTORY_SEPARATOR //当前操作系统目录分隔符 Win \ Linux /
//魔术常量 根据代码所处的位置变化,函数的命名 对象等
__DIR__ // 当前脚本所在的目录
__FILE__ // 当前脚本物理路径的绝对地址【文件名和后缀】
__LINE__ // 当前代码所在的行号 【】
__FUNCTION__ // 在函数内部使用,表示当前函数的名称
__CLASS__ // 在对象内部使用,表示当前对象名称
__TRAIT__ // 。。。。。。。,。。。。TRAIT
__METHOD__ // 。。。。。。。,。。。。方法
__NAMESPACE__ // 。。。。。。。,所在的命名空间
自定义常量
系统的状态码或者标识位
- define(
n
a
m
e
,
name,
name,value) 定义常量
- 可以使用参数,定义动态的常量
- const 关键字声明常量
- 固死的声明常量
- defined() 判断常量是否定义
- 使用未定义的常量
- 重复定义了常量
- 常量值的类型可以任意
- 使用常量
if(!defined('PHP_OS')){
define('PHP_OS','WinNT');
}
const PAY_WAY_WEIXIN = 1;//
echo PAY_WAY_WEIXIN;
echo PHP_OS;
echo __DIR__;
echo __LINE__;
//变量一定要带上$ 否则当初常量处理
第四章 PHP数组与字符串
数组和字符串是PHP中最重要的两种数据类型
数组中的元素的数据类型不限制
数组及处理
创建数组
PHP数组中的元素可以是任意类型的数据
- Notice: Undefined offset: 8 索引数组越界
<?php
error_reporting(E_ALL & ~E_NOTICE);
$color = []; //推荐的写法
$font_size = array();//也支持这样定义
//索引数组 ;访问 0------【长度-1】
$margin = [
"top",
"right",
"bottom",
"left"
];
$margin[0];//top
$margin[3];//left
$margin[4];//访问第五个元素,数组中不存在,E_NOTICE,数组越界
$margin[0] = '新的值';//修改元素
$margin[] = 'left_top';//新增元素 数组下标会自增
unset($margin[0]); //把数组的第一个元素删除
unset($margin); //手动删除数据,释放内存。
//脚本结束之前,不会自动回收垃圾数据,为了及时释放内存空间,可以手动删除变量
isset($margin[4]);//判断数组中是否存在小标是4的元素
isset($margin); //判决变量是否定于
count($margin); //统计数组中元素的个数
count($margin,true); //递归统计数组中元素的个数
//推荐的写法,这个数组有4个元素
?>
索引数组和关联数组的定义
$margin = ["top", "right", "bottom", "left"]; //索引数组,从0开始
//关联数组 明确的键值对【key=>value】,索引数组的01235....不能明确表示元素的含义
$margin = [
"t"=>"top",
"r"=>'right',
'b'=>"bottom",
'l'=>'left'
];//关联数组
$margin['t'];//top
$margin['tl'];//访问元素,数组中不存在,E_NOTICE,数组越界
$margin['tl'] = 'top_left';
调试输出数组信息
$margin = ["top", "right", "bottom", "left"]; //索引数组,从0开始
echo '<pre>';//输出格式化标签
var_dump($margin);
echo '<pre>';
print_r($margin);
//封装函数处理变量的调试输出
function dump($var) {
ob_start();
var_dump($var);
$output = ob_get_clean();
$output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
$output = '<pre>' . $output . '</pre>';
echo ($output);
}
数组的访问
error_reporting(E_ALL);
$margin = ["top", "right", "bottom", "left", "8a" => "test1.php", "abc"];
echo $margin[0];//访问索引数组
$margin = ["t" => "top", "r" => 'right', 'b' => "bottom", 'l' => 'left'];
echo $margin["t"];//访问关联数组
//Notice: Undefined offset: 数组越界【下标不存在】
多维数组及访问
$margin = [
"top",
"right",
"bottom",
"left",
"8a" => "test1.php",
"abc",
[
1,
2,
3,
[
1,
2,
30
]
]
];
//没有指定下标的元素,自动从当前数组数字下标最大值+1
echo $margin[0];//top
echo $margin[5][0];//1
echo $margin[5][3][2];//30
统计数组有几个元素
$margin = ["top", "right", "bottom", "left", "8a" => "test1.php", "abc", [1, 2, 3, [1, 2, 3]]];
echo count($margin);//7 常规用法,只计算一维数组个数
echo count($margin, true);//14 递归计算多维数组
数组的遍历
$margin = ["top", "right", "bottom", "left", "8a" => "test1.php", "abc", [1, 2, 3, [1, 2, 3]]];
//索引数组
$len = count($arr);
for($i=0;$i<$len;$i++){
echo $arr[$i];
}
//关联数组
$margin = ["t" => "top", "r" => 'right', 'b' => "bottom", 'l' => 'left'];
foreach($margin as $kk=>$vv){
echo $kk;//t
echo $vv;//top
}
//如果不需要key值,可以直接这样
foreach($margin as $vv){
echo $vv;//top
$vv = '新的值'; //这样方式修改,不会影响到数组本身
}
//遍历时,两种可以改变原数组的方法
foreach($margin as &$vv){
echo $vv;//top
$vv = '新的值'; //这样方式修改,会影响到数组本身
}
foreach($margin as $kk=>$vv){
echo $kk;//t
$margin[$kk] = '新的值';//这样方式修改,会影响到数组本身
}
数组作为函数的参数
参数默认是赋值的形式进行传参
$array = [
'10086','PHP是世界上最简单的语言'
];
//数组参数传参的默认形式
$res = changeArr($array);
function changeArr( $array){
$array[0] = 123;
return 1;
}
echo '<pre>';
var_dump($array);
创建指定范围数组
使用系统函数:
函数名
作用
参数【普通,引用】
返回值
error_reporting(E_ALL);
echo '<pre>';
$arr1 = range(1, 20); //1,2,3,4,5....10.....20
$arr2 = [];
print_r($arr1);
$arr1 = range(1, 20, 3);//1 4 7 10 13 16 19
print_r($arr1);
$arr1 = range('a', 'z');//a b c d .....m.......z
print_r($arr1);
//range(0,9)
//a-z
//生成8位数的随机数(0-9a-z)
//
get_rand_str();//jkdfs2555
get_rand_str(16);
function get_rand_str(int $len=8){
$num = range(0,9);
$num_2 = range('a','z');
//执行数组的合并
$arr = array_merge($num,$num_2);//0-9a-z
$rand_str = '';
for($i=0;$i<$len;$i++){
//索引数组的随机下标 0 count($arr)-1
$rand_str .= $arr[mt_rand(0,count($arr)-1)];
}
return $rand_str;
}
function get_rand_str_2(int $len=8){
$num = range(0,9);
$num_2 = range('a','z');
//执行数组的合并
$arr = array_merge($num,$num_2);//0-9a-z
shuffle($arr);//打乱顺序
array_slice($arr,0,$len);//数组
return implode('',$arr);
}
检测数组中是否存在某个值(value)
error_reporting(E_ALL);
$student = [
'id' => '10011',
"sex" => 1,
"username" => "PHP之父",
"year" => 1995
];
//1 30
/**************** in_array(值,数组) **************************/
//见名如意
$is_exists = in_array(10011, $student);
var_dump($is_exists);//true
$is_exists = in_array(10011, $student, true);// == ===
//key value
var_dump($is_exists);//false
/**************** array_search(值,数组) **************************/
var_dump(array_search("10011",$student)); //存在则返回key,不存在返回NULL
检测数组中是否存在某个键(key)
error_reporting(E_ALL);
$student = [
'id' => null,
"sex" => 1
];
/*************** array_key_exists *******************/
var_dump(array_key_exists("id", $student)); //true
/*************** isset *******************/
//某个变量是否存在【值不能是NULL】
$age = NULL;//unset()
isset($age);//false
var_dump(isset($student['id']));//
数组和字符串相互转化
$student = [
"id" => 100001,
"sex" => 1,
'name' => 'PHP之父'
];
$str = implode(",",$student); // 100001,1,PHP之父
echo $str;
$new_arr = explode(",",$str);
print_r($new_arr);
取数组中的key和value分别为新的数组
error_reporting(E_ALL);
//INSERT INTO `students`(id,sex,name)VALUES(100001,1,PHP之父)
$student = [
"id" => 100001,
"sex" => 1,
'name' => 'PHP之父',
'mobile'=>'15260362525'
];
//SQL
//INSERT INTO tab_name ()values()
$keys = array_keys($student);//id,sex,name
$vals = array_values($student);//100001,1,'PHP之父'
$sql = 'INSERT INTO `students`(' . implode(",", $keys) . ')VALUES(' . implode(",", $vals) . ')';
var_dump($sql);
把索引数组的值赋值给某些变量
- list函数
error_reporting(E_ALL);
$student = ['PHP之父', 123, 456];
list($a, $b) = $student; //数组中的0,1对应的值赋值给$a,$b
print_r($a);
print_r($b);
数组堆栈操作【掌握】
- 栈【先入后出,后入先出】
- 堆【先入先出,后入后出】
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KicAtewp-1655041103800)(chapter03.assets/image-20220304112326506.png)]
$student = [4, 5, 6];
$num = array_pop($student);/*后面的先出来*/
var_dump($num);
var_dump($student);
$student = [4, 5, 6];
$num = array_shift($student);/*前面的先出来*/
var_dump($num);
var_dump($student);
$student = [4, 5, 6];
array_push($student, 7, 8, 9); //添加到数组的尾部
var_dump($student);
$student = [4, 5, 6];
array_unshift($student, 7, 8, 9); //添加到数组的头部
var_dump($student)
数组的指针操作【了解】
$student = ['PHP之父', "as" => 123, 456];
echo current($student);
echo next($student);
echo end($student);
reset();
prev();
each();
交换数组的键和值【了解】
$student = ['PHP之父', "as" => 123, 456];
array_flip($student);
数组的遍历【重点】
- for
- foreach
$arr = [
"a"=>1,
"b"=>2,
"c"=>3
];
//a=1&b=2&c=3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0krM08l3-1655041103802)(chapter03.assets/image-20220304154300953.png)]
数组的排序
//排序算法动画 http://tools.jb51.net/static/api/paixu_ys/index.html
- sort---------rsort 按值升序 ,重新建立索引
- asort-------arsort 按值升序 ,键名不变
- ksort【掌握】-------krsort() 按键名升序 ,键名不变
数组重新排序
- shuffle 随机排序,重新建立索引
- array_reverse 原顺序反过来
数组合并与去重
- array_merge
- array_unique
数组与JSON
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
- json_encode
- json_decode
//https://www.php.net/manual/zh/json.constants.php
JSON_UNESCAPED_SLASHES (int)
不要编码 /。 自 PHP 5.4.0 起生效。
JSON_UNESCAPED_UNICODE (int)
以字面编码多字节 Unicode 字符(默认是编码成 \uXXXX)。 自 PHP 5.4.0 起生效。
不能echo一个数组 Array
字符串及处理
单引号、双引号、转义字符、heredoc
- 本身就是一个字符串,字符串中又没有其他字面量的字符串,不要特意给他戴上双引号
$op = 'a=1';
$column = 'id =1';
echo $op.$column;
/******************/
echo "$op"."$column";//不允许出现了
/********************/
字符串格式化【了解】
- printf() 格式化并输出
- sprintf() 得到格式化后的内容
function pri(){
//格式化
echo '';
}
function prif(){
//格式化
return '';
}
%s | 格式化为字符串 | ||
---|---|---|---|
%f | 格式化为浮点数 | ||
%d | 格式化为整数 | ||
%010s | 格式化为字符串,不足10位时前补0 |
统计字符串的长度【掌握】
编码格式:UTF-8
//文件编码是UTF-8
//输出的内容编码格式也是UTF-8
- strlen 在UTF8编码时,一个中文按3个长度计算
- mb_strlen 在UTF8编码时,一个中文按1个长度计算
error_reporting(E_ALL);
$username = 'china猜呐';
echo strlen($username); //5+6=11
//morebits
echo mb_strlen($username); //5+2=7
大小写转换
error_reporting(E_ALL);
$str = 'hello PHP';
echo strtolower($str);//小写
echo strtoupper($str);//大写
//X x
echo ucfirst($str);//对首字母转为大写
字符串裁剪【掌握】
$str = ' hello PHP ';
echo trim($str);
echo ltrim($str);
echo rtrim($str);
/*------------------------*/
$tel = '15260363636';
echo substr($tel,0,3).'****'.substr($tel,-4);
//中文使用mb_substr()
字符串查找
strpos(string haystack,mixed needle, int $offset = 0): int
返回 needle 在 haystack 中 首次出现 的数字位置。
找不到返回 false
区分大小写
注意第一个位置是0,所以判断的时候要注意 0 == false
strrpos
(PHP 4, PHP 5, PHP 7, PHP 8)
strrpos — 计算指定字符串在目标字符串中 最后一次出现 的位置
stripos strripos 不区分大小写
$email = '991850594@qq.com';
echo strpos($email, "@");
echo strrpos($email, "@");
echo strstr($email, "@");
echo strstr($email, "@", true);
字符串与ASCII编码
- ord() 获取字符对应的ascii码
- chr() 把ascii转为字符
48-57=========0-9
65-90=========A-Z
97-122========a-z
error_reporting(E_ALL);
//获取0-9A-Za-z组成的随机10位数
//激活码 唯一 没有规律 乱序
$arr1 = range(48, 57);//0-9
$arr2 = range(65, 90);//A-Z
$arr3 = range(97, 122);//a-z
$arr4 = array_merge($arr1, $arr2, $arr3);//合并
//对数组的每个元素执行回调
array_walk($arr4, function (&$i) {
$i = chr($i);//转化为字符串
});
shuffle($arr4);
$arr5 = array_slice($arr4, 0, 8);
echo implode("", $arr5);//激活码
字符串替换
$path = __DIR__;
echo $path;
echo str_replace("\\", "/", $path);
$query = 'a=1&b=2&c=3';
echo str_replace(["=", "&"], ["=>", ","], $query);
字符串与HTML
输出:PHP预处理 最终还是输出字符串【HTML】
输入: 表单
最高原则:任何输入数据信息都是不可信
用户有哪些途径可以进行输入
- 表单数据提交 $_GET $__POST
- cookie数据传输 $_COOKIE
- URL中的参数 $_GET $__REQUEST
XSS攻击【跨站脚本攻击(Cross Site Scripting)缩写为XSS】
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容
网站A:建设银行进行转账张三
网站B:被植入网站A中转账的连接
<a>123</a> 将特殊字符转为html字符实体 <a>
<script ></script> //正则表达把标签部分直接去除
- htmlspecialchars 将特殊字符转为html字符实体
- htmlspecialchars_decode
- strip_tags
字符串与加密
- 解决用户密码如何保存的问题
- 解决登录验证密码正确的问题
https://www.php.net/manual/zh/faq.passwords.php#faq.passwords.fasthash
时序攻击:举一个最简单的计时攻击的例子,某个函数负责比较用户输入的密码和存放在系统内密码是否相同,如果该函数是从第一位开始比较,发现不同就立即返回,那么通过计算返回的速度就知道了大概是哪一位开始不同的,这样就实现了电影中经常出现的按位破解密码的场景。密码破解复杂度成千上万倍甚至百万千万倍的下降。
最简单的防御方法是:“发现错误的时候并不立即返回,而是设一个标志位,直到完全比较完两个字符串再返回”
-
密码能否明文保存?
- 注册时输入123456,要保存密码123456
- 登录时输入123456,要验证123456
-
md5()
-
单向不可逆
-
32位16进制的字符串
-
只要加密的内容不变,加密的结果也不变
-
只要加密的结果确定,被加密的明文也是确定
-
不同用户注册时输入的密码是一致的
- 假如把加密的结果保存在数据库
- 假如数据库窃取,数据库用户信息泄露
- e10adc3949ba59abbe56e057f20f883e 123456
- 破一得无数123456【彩虹表】
- 穷举破解
$password = md5($_POST['password']); //假如说网站遭受攻击? //首先说明的是:平台有价值 //然后才是漏洞 123456 e10adc3949ba59abbe56e057f20f883e 123456 123456 e10adc3949ba59abbe56e057f20f883e 123456 //1000W 100W 123456 md5() 123456 //100W 一种123456 加密结果100w种 123456 md(123456ABC123) 123456 md(123456ABD123) //加上随机数进行加密之后 登录时如何验证密码是否正确?
-
如何避免同样的明文加密结果一致?
- 只有一种方法,就是修改被加密的内容
- A:123456加上随机数【加盐处理】 123456ABC
- B:123456 加上随机数【加盐处理】 123456GDF
-
使用随机数后如何验证密码的正确与否?
- 要记录与之对应的随机数【随机数也要保存】
- A:123456ABC
- B:1234556GDF
-
-
仅使用一层md5也不是好的方案?
- 加密的方法越复杂越好【破解难度越高,成本越大】
- md5(123456ABC) 可能就已经存在与之对应的彩虹表
- md5(md5(123456ABC).$salt)
- md5( s a l t . m d 5 ( 123456 A B C ) . salt.md5(123456ABC). salt.md5(123456ABC).salt)
-
md5_file
- 获取文件的信息摘要
- 只要文件的信息是一致的,最终结果也是一致的
- 100万个用户发布同一张图片
- 不需要存储100万张图片
- 根据md5_file如果是一致的,只保留一张
-
password_hash
-
password_verify
-
hash_equals
正则表达式
正则表达式是对字符串操作的一组逻辑公式。正则表达式作为模板与搜索的字符串进行匹配
作用:
-
判断给定的字符串是否匹配正则表达式
- 手机号码
- 用户名的限制【不能出现中文,特殊符号】
- URL
-
用新文本替换匹配的文本
- XXS <()><()/> <
- 敏感数据的替换
-
将字符串拆分为更小的信息块,从字符串中获取特定部分
- a|b|c|d
-
URL重写
伪静态处理【有利于SEO】
goods.php?id=1&type=12&brand_id=123【不优雅 不简洁 不利于SEO】
利于Apche、Nginx的重写机制把URL转为伪静态
goods-1-12-123.html
- https://item.jd.com/1004-27060-63162.html
- https://item.jd.com/?shop_id=1004&goods_id=27060&type_id=63162
组成:
- 正则表达式由一组普通字符和一些特殊字符【元字符】以及模式修正符组成
- 大小写字母、数字、标点符号、非打印字符【换行回车等】、双引号、单引号等普通字符
元字符
字符 | 描述 | 示例 |
---|---|---|
\ | 将特殊字符转为普通字符[]{}/-?* | \. 、\-、 \\ 一般需要双引号 |
^ | 匹配字符串的开始位置 | 匹配字符串开始的位置,字符串中有换行时,要多行匹配需要使用修正符m【此时表示每一行的开始】【字符串的开始或者每一行的开始部分】 |
$ | 匹配字符串的结束位置 | 匹配字符串结束的位置 |
* | 0 1…N | |
+ | 1…N | |
? | 0或1 | 匹配的字符规则:要么没有,要么只匹配一次 http[s]? |
{n} | 连续出现n次 | n是一个整数 |
{n,m} | 最少n次最多m | {1,} {0,1} |
.(点) | 匹配除换行符之外的任何字符 | 12\.55 |
x|y | 匹配x或y | 2022-04-05 2022/04/15 [-|/] |
[abc] | 匹配任意一个字符 | 2022-04-05 2022/04/15 [-/] |
[^abc] | 匹配不在括号中的任意字符 |
预定义字符
对某一类字符集进行简写
字符 | 说明 |
---|---|
\d | [0-9] |
\s | 匹配不可见字符【换行、空格等】 |
\w | [a-zA-Z0-9_] |
模式修饰符
https://www.php.net/manual/zh/reference.pcre.pattern.modifiers.php
修饰符 | 描述 |
---|---|
i | 忽略大小写 |
m | 多行匹配,^表示每一行的开头 |
s | 使.可以匹配换行符等 |
U | 禁止贪婪匹配 |
后向引用
场景:后面的匹配结果跟之前匹配的结果需要一致的时,可以使用
把前面匹配的结果进行引用。()
不捕获(?:)表示括号种的的内容不捕获
符号 | 说明 |
---|---|
\num | 对匹配的引用 |
\g{num} | 对匹配的引用 |
\g{-num} | 对匹配的反向引用 |
${num} | 对匹配的引用 |
$date = '2022-04/19';
//2022/04/19 合法
// 2022-04/19 非法
// 2022/04-19 非法
$pattern = '#\d{4}([-/])\d{2}\1\d{2}#'; //单引号
"#\d{4}([-/])\d{2}\1\d{2}#" //无效
"#\d{4}([-/])\d{2}\\1\d{2}#"
\1 表示引用前面第一个被捕获的内容 这种方式会存在歧义 \12 是第一个捕获后面是2,还是第12个捕获
$pattern = "#\d{4}([-/])\d{2}\g{1}\d{2}#";
贪婪匹配
非贪婪匹配
不捕获
//?:
preg_match('/<(?:.*)\s+src=(.*?)>/',$html, $match);
print_r($match);
/*
rewrite ^/article_cat-([0-9]+)-([0-9]+)(.*).html$ /article_cat.php?id=$1&page=$2 last;
rewrite ^/article_cat-([0-9]+)(.*).html$ /article_cat.php?id=$1 last;
rewrite ^/article-([0-9]+)(.*).html$ /article.php?id=$1 last;
rewrite ^/merchants-([0-9]+)(.*).html$ /merchants.php?id=$1 last;
rewrite ^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)-(([a-zA-Z])+([^-]*)).html /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5&act=$6 last;
*/
$user = 'HelloWorldJames';
$user = preg_replace('{([A-Z])}','_\\0',$user);
var_dump($user);
$a = '_Hello_World_James';
$user = preg_replace('{_{1}}','',$a,1);
var_dump($user);
$str = '那是2022/03-13的上午';
preg_match('#(\d{4})-(\d{2})-(\d{2})#',$str,$matches);
var_dump($matches);
preg_match('#(\d{4})([-/])(\d{2})\\2(\d{2})#',$str,$matches);
var_dump($matches);
$str = '<span class="bjh-p">记者获悉</span>';
$ss = preg_replace('#<.*>#','',$str);
$str = '<span class="bjh-p">记者获悉</span>';
$ss = preg_replace('#<.*?>#','',$str);
第五章 PHP常用功能模块
文件目录系统
目录文件权限
777
RWX
![(https://typora-ykh.oss-cn-beijing.aliyuncs.com/webfullstack/5237297_2_thumb.jpg)
目录操作
创建目录
目录的访问权限【读写执行124】
删除目录
空目录才能被删除
使用目录句柄打开、读取、关闭目录操作
一个函数直接读取目录信息
目录相关函数
- is_dir
- dirname
- file_exists
- filesize
文件操作
使用文件句柄打开、读取、写入、关闭文件操作
一个函数读取文件
- 读取全部,返回数组。包含每一行信息
- 读取全部或者部分,返回字符串
- 读取一行
- 读取一个字符
- 读取全部并输出
一个函数写入文件
换行和回车
-
机械打字机有回车和换行两个键作用分别是:
换行就是把滚筒卷一格,不改变水平位置。
回车就是把水平位置复位,不卷动滚筒。 -
Enter = 回车+换行(\r\n) 注:\r\n连用时,不能调换顺序
unix换行:\n(0x0A)
MAC回车:\r(0x0D)
WIN回车换行:\r\n(0x0D,0x0A)
访问文件的模式
模式 | 说明 | 注意 |
---|---|---|
r | 从文件头开始读,只读 | 文件不存在报错E_WARNING |
r+ | 从文件头开始读写,读写 | 文件不存在报错E_WARNING,追加写入 |
w | 文件指针指向文件头,只写 | 已有内容会被删除【清空原有内容】,文件不存在尝试创建 |
w+ | 文件指针指向文件头,读写 | 已有内容会被删除,文件不存在尝试创建 |
a | 文件指针指向文件尾,只写 | 内容添加在末尾,文件不存在尝试创建 |
a+ | 文件指针指向文件尾,读写 | 内容添加在末尾,文件不存在尝试创建 |
x | 文件指针指向文件头,写入 | 文件存在返回false,E_WARNING【不允许文件已经存在】 |
x+ | 文件指针指向文件头,读写 | 文件存在返回false,E_WARNING |
b | 用在以上模式之后,配合使用 | 读取二进制文件时必须使用【仅window区分二进制和文件】【移植性】 |
文件操作相关函数
文件上传与下载
上传
-
enctype=multipart/form-data
传输二进制数据 -
action='post'
必须使用post -
$_FILES
-
move_uploaded_file
move_uploaded_file();
文件下载
- 响应头函数
header(Key:Value)
响应头参数 | 说明 | 示例 |
---|---|---|
Content-Type | 指示内容的格式 | Content-Type: application/octet-stream |
Content-Length | 内容长度 | strlen,filesize |
Content-Disposition | 指示如何处理响应内容 | inline :直接在浏览器页面显示 attchment :以附件形式下载attachment;filename=2022.doc |
Content-Transfer-Encoding | 非必须 | binary |
Expires | 非必须 | gmdate(“D, d M Y H:i:s”, time() + 3600) . ’ GMT’; |
Cache-control | 非必须 | max-age=3600 |
/**
* 获取文件类型信息
* @param string $filename 文件名
* @return string
*/
header("K:v");
function getMimeType($filename)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
return finfo_file($finfo, $filename);
}
延申Cache-Control的特性
申明:Cache-Control 只支持get请求
- 可缓存性,包括:
- public:在HTTP请求返回的过程中,在cache-control设置了public这个值,代表这个HTTP请求返回的内容中所经过的任何路径当中,包括一些中间的HTTP的代理服务器以及发出这个请求的客户端浏览器都可以对这个返回的内容进行缓存的操作。
- private:表示发起请求的这个浏览器才能进行缓存的
- no-cache:每次发送请求都要去服务器验证一下,如果服务器告诉可以使用缓存,才使用本地缓存
- 到期:
- max-age=
- s-maxage= 代替max-age,只有在代理服务器中才会生效
- max-stale= 即使这个缓存已经过期了,只要在max-stale这个时间内,还可以使用过期的缓存。
- 重新验证:
- must-revalidate:在设置了max-age这个缓存当中,如果已经过期了,必须去原服务端去重新获取资源来验证是否真的过期
- proxy-revalidate:与must-revalidate差不多,这个是用在缓存服务器中的
其它:
- no-store:本地和代理服务器都不可以进行缓存,永远要拿新的内容
- no-transform:主要用在proxy-服务器中。告诉代理服务器不要改动返回的内容
说明:这些设置的头,只是 一个规范,但是这个代理服务器可以完全不按照这个规范去做。
图形处理
生成图形验证码
生成缩略图
日期时间操作
第六章 面向对象
函数式的过程化编码风格简单但不易管理和维护,代码比较零散杂乱
引入对象可以保护程序中出现的数据和方法
基本概念
主要特征
- 封装
- 将数据和代码进行保护,避免外界任意干扰
- 继承
- 继承实现了代码的复用
- 继承的新类可以对已有的类进行修改和扩展
- 多态
- 不同类对于同一操作具有不同行为
- 机制
- 抽象或接口
- 继承或实现
- 方法重写
- 调用时,参数类型为父类,实际参数为子类
类和对象的关系
- 类是抽象的,对象是具体的
- 类是创建对象的模板
- 类的所有对象都有相同的数据结构,共享相同的实现操作
- 同一类的不同对象可以有不同的状态
命名空间【目录】
-
非必须
-
命名空间的名称跟目录保持一致
-
namespace
-
避免命名冲突
-
目录名称小写
https://www.php.net/manual/zh/language.namespaces.rationale.php具体举个例子,文件
foo.txt
可以同时在目录/home/greg
和/home/other
中存在,但在同一个目录中不能存在两个foo.txt
文件。另外,在目录/home/greg
外访问foo.txt
文件时,我们必须将目录名以及目录分隔符放在文件名之前得到/home/greg/foo.txt
。这个原理应用到程序设计领域就是命名空间的概念在 PHP 中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:
- 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径
类的定义
-
类的文件名
- 一个类单独一个文件名
- 文件名跟类名保持一致
- 文件名使用驼峰法【单词的首字母大写】
- 文件的后缀【.php .class.php】
-
命名空间【非必要】
-
类名
-
属性
- 公开的
- 受保护的
- 私有的
-
方法
- 公开的
- 受保护的
- 私有的
-
构造方法,非必须
-
类常量
<?php
//站点的根目录 D:\phpstudy_pro\WWW\www.oop.com
error_reporting(E_ALL);
站点的根目录
define('ROOT_PATH', str_replace("\\", '/', __DIR__) . "/");
//echo ROOT_PATH;D:/phpstudy_pro/WWW/www.oop.com/
//应用的目录
define('APP_PATH', ROOT_PATH . "app/"); //应用的目录
//实例化 先引入类文件【手动 自动】
require_once APP_PATH . 'oop/common/Test.php';
$test = new app\oop\common\Test(1, md5('123456'), '100000000');
var_dump($test);
//可变变量 变量函数 变量对象
$class_name = 'app\oop\common\Test';
$test2 = new $class_name(2, md5('123456'), '100000000');
//toString()
var_dump($test2);
echo "访问public<br>";
$test2->id = 10; //public 在外部可以直接写入或者修改
echo $test2->id; //读取属性
// echo "访问protecteecho "访问private<br>";
// echo $test2->balance; //读取属性d<br>";
// echo $test2->password; //读取属性
//类中本来没有属性id2
echo '访问一个不存在的属性id2<br>';
//访问一个不存在的属性
//echo $test2->id2; //
//设置一个不存在的属性【无中生有】
echo '类中本来没有属性id2<br>';
$test2->id2 = 100;
$id2 = 'id';
//$$id2
echo $test2->$id2; //访问可变的属性
echo $test2->getBalance();
//访问对象的可变方法
echo '访问对象的可变方法<br>';
$func_name = 'getPassword';
echo $test2->$func_name();
echo '访问对象的常量<br>';
echo $test2::VERSION;
echo '访问类名的常量<br>';
echo app\oop\common\Test::VERSION;
类的实例化
- 引入类文件
- 自动引入
- 手动引入
//手动引入类文件
require_once APP_PATH . 'oop/common/Father.php';
//实例化 [命名空间+类名]
$father = new app\oop\common\Father();
//可变变量 变量函数 变量对象
$clas_name = 'app\oop\common\Father';
$father2 = new $clas_name();
//构造函数
public function __construct($name, $age, $wallet, $id_card='3505') {
echo '实例化时自动调用构造方法';
}
类的访问
静态属性和方法
- 定义
- 访问
$test1::$times
app\oop\common\Test::$times
- 可以不需要实例化
- 对象也可访问
/************普通的成员变量*********************/
$test1 = new $class_name(2, md5('123456'), '100000000');
$test1->id++;
$test1->id++;
echo $test1->id; //修改不会影响到该类的其他对象
$test2 = new $class_name(2, md5('123456'), '100000000');
echo $test2->id; //不会被$test1影响
/************类的静态属性*********************/
public static $times = 0;
$test1::$times++;
$test1::$times++;
echo "======" . $test1::$times . "========";//2会影响该类的其他对象
$test2 = new $class_name(2, md5('123456'), '100000000');
echo "======" . $test2::$times . "========";//2 被$test1操作影响
public static function getMyClassName() {
//静态方法中不存在$this
//Uncaught Error: Using $this when not in object contex
return __CLASS__;
}
echo app\oop\common\Test::getMyClassName();
类的继承
-
extends
- 单继承
-
子类父类构造方法
- 子类没有 父类有公有的构造方法
- 子类没有 父类有非公有的构造方法
- 子类有 父类有的构造方法
-
parent::
- 访问父类的方法
- 访问父类的常量
- 访问父类的静态属性
-
方法重写
-
常量重写
-
属性重写
final关键字
只能修饰类或者方法,表示不能被继承或者不能被重写
traits机制
- 类的水平扩展
抽象类
- 不能被实例化
- 有一个抽象方法则必须是抽象类
- 子类必须实现抽象类中抽象方法
- 抽象方法不能有方法体
- 抽象类可以有非抽象方法,类常量,普通属性
接口
- 接口中的方法不能有方法体
- 不能有成员变量
- 方法只能public修饰,所有可以不要
魔术方法
self static
<?php
namespace lab09\app\home\controller;
class Index extends Father{
//
public $name = '一无所有';
public const RAND_TYPE = "789";
public function getWallet($a=1,$b=2){
//echo self::RAND_TYPE;
echo parent::getWallet();
return $this->wallect;
}
public function __construct(){
parent::__construct();
//parent::getWallet();
echo '子类构造方法';
}
}
namespace lab09\app\home\controller;
class Father extends Grand{
//
private $wallect = '2个亿'; /*本身 子类*/
public const RAND_TYPE = 158888;
public function getWallet($a=1,$c=2){
//var_dump($this);
var_dump(self::RAND_TYPE);
var_dump(static::RAND_TYPE);
return $this->wallect;
}
public function __construct(){
echo '父类构造方法';
}
}
namespace lab09\app\home\controller;
class Grand{
//
private $wallect = '2个亿'; /*本身 子类*/
public const RAND_TYPE = 158;
public function getWallet($b,$c){
return $this->wallect;
}
public function __construct(){
echo '祖先类构造方法';
}
public function haha(){
echo __FUNCTION__;
}
}
第七章-构建PHP互动网页
表单数据提交
直接使用form标签进行提交
属性 | 说明 |
---|---|
action | 数据提交的地址【URL绝对地址】【相对地址 / ./】 |
method | 数据提交的方法【get post】【文件上传一定要post】 |
enctype | 数据的编码格式【】 |
如果是复选框
<input type="checkbox" name="course[]" value="PHP5" >
<input type="checkbox" name="course[]" value="PHP7" >
<input type="checkbox" name="course[]" value="PHP8" >
<input type="checkbox" name="course[]" value="PHP9" >
<!--提交到服务端是一个数组-->
$_POST['course'][]="PHP5";
$_POST['course'][]="PHP7";
$_POST['course'][]="PHP8";
$_POST['course'][]="PHP9";
如果是单选框
<input type="radio" name="course" value="PHP5" >
<input type="radio" name="course" value="PHP7" >
<input type="radio" name="course" value="PHP8" >
<input type="radio" name="course" value="PHP9" >
$_POST['course']="PHP5";
表单提交的数据全部需要进行安全过滤
$_GET
$_POST
$_REQUEST
URL处理
alert("用户名错误");
<?php
namespace tools;
class URL{
public $http_host;
public $server_name;
public $port ;
public $ip;
public $server_software;
public $method;
public $query;
public $script_name ;
public $request_time;
public $request_scheme;
public $server_protocol;
public $user_agent;
public function __construct(){
$this->http_host = $_SERVER['HTTP_HOST'];
$this->server_name = $_SERVER['SERVER_NAME'];
$this->port = $_SERVER['SERVER_PORT'];
$this->ip = $_SERVER['REMOTE_ADDR'];
$this->server_software = $_SERVER['SERVER_SOFTWARE'];
$this->method = $_SERVER['REQUEST_METHOD'];
$this->query = $_SERVER['QUERY_STRING'];
$this->script_name = $_SERVER['SCRIPT_NAME'];
$this->request_time = $_SERVER['REQUEST_TIME_FLOAT'];
$this->request_scheme = $_SERVER['REQUEST_SCHEME'];
$this->server_protocol = $_SERVER['SERVER_PROTOCOL'];
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
}
//页面跳转【重定向】
public function redirect($url){
//
header("Location:".$url);
}
public function alertMsg($msg,$url,$timeout=3){
echo '<script>alert("'.$msg.'");</script>';
if($url){
echo '<script>setTimeout(function(){
window.location.href="'.$url.'";
},'.($timeout*1000).')</script>';
}
}
//执行编码
public function encode($url){
return urlencode($url);
}
public function decode($url){
return urldecode($url);
}
}
会话管理
HTTP请求是无状态,不能识别是否是同一个用户。借助cookie 、session实现页面间数据共享【持久化】。
cookie会话
- 存储客户端【浏览器设置】【持久化】
- 客户端中可以任意修改、添加、删除Cookie【不安全】
- 存储的大小有限制【4-8kb】
- 存储
- 传输
- Cookie会作为每次HTTP请求头的一部分
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z8nzoVzW-1655041103805)(C:\Users\Administrator.USER-20190905XB\AppData\Roaming\Typora\typora-user-images\image-20220524102038106.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbVarlOZ-1655041103806)(D:\phpstudy_pro\WWW\www.oop.com\images\image-20220524103153594.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJyNBXq3-1655041103806)(D:\phpstudy_pro\WWW\www.oop.com\images\image-20220524103324472.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xFhfVlAz-1655041103807)(D:\phpstudy_pro\WWW\www.oop.com\images\image-20220524103524434.png)]
<?php
namespace lab09\tools;
class Cookie{
public $name;
public $value = "";
public $expires = 0;
public $path = "";
public $domain = "";
public $secure = false;
public $httponly = false;
public function __construct($expires=0,$path="/",$domain= "",$secure = false,$httponly = false){
$this->expires = $expires;
$this->path = $path;
$this->domain = $domain;
$this->secure = $secure;
$this->httponly = $httponly;
}
//设置cookie 1800
//设置成功后响应头中会设置cookie信息
//客户端拿到cookie信息之后会进行保存
public function setCookie($name,$value,$expires=0){
//time() 当前时间戳
$expires = $expires>0?(time()+$expires):0;
return setcookie($name,$value,$expires,$this->path,$this->domain,$this->secure,$this->httponly);
}
//获取cookie
public function getCookie($name){
return isset($_COOKIE[$name])?$_COOKIE[$name]:"";
}
//删除
public function delCookie($name){
$_COOKIE[$name] = null;
setcookie($name,'',-1,$this->path,$this->domain,$this->secure,$this->httponly);
}
}
session会话
- 存储在服务端【持久化】
- 客户端不能修改会话相关的数据【相对安全】
- 存储的大小理论上不限制有限制
- 一般通过cookie来配合完成会话
- 默认使用文件存储在磁盘【文件读写操作 IO】
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePIBNOLu-1655041103807)(D:\phpstudy_pro\WWW\www.oop.com\images\image-20220524104510947.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UWlvlR28-1655041103808)(D:\phpstudy_pro\WWW\www.oop.com\images\image-20220524104627111.png)]
<?php
namespace lab09\tools;
class Session{
public function __construct(){
//默认不启用session
//所有需要先启用
session_start();
}
//设置
public function setSession($name,$val){
$_SESSION[$name] = $val;
}
//读取
public function getSession($name){
return isset($_SESSION[$name])?$_SESSION[$name]:"";
}
//删除某个key
public function delSession($name){
$_SESSION[$name] = null;
}
//删除全部
public function delAllSession($name){
$_SESSION = null;
//把Cookie中的PHPSESSID删除
}
}
第八章 数据库基础
数据库的分类
关系型数据库
数据有
MySQL
SqlServer
Oracle
非关系型数据库[NoSQL]
Redis
MongoDB
SQL语句的分类
DDL(Database Define Language)(用来定义的SQL语句 数据库 表 字段)
DCL(Database Control Language) (用来控制数据库的访问权限)
DML(Database Modify Language) (数据表进行修改 新增 编辑 删除)
DQL(Database Query Language) (用来查询数据库)
创建数据库
名称【项目】
英文、全部小写
下划线
数字
字符集
utf8
utf8mb4【有些字符需要4个字节表示】【表情符号一般都是4个字节来表示】
排序规则
utf8_general_ci
utf8mb4_general_ci
CREATE DATABASE student_manager
CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
创建表
名称【项目模块】
英文、全部小写
下划线
数字
存储引擎
InnoDB
MyISAM
字符集
默认
排序规则
默认
创建表字段
名称【实体信息】
数据类型是字符型字符集
默认
数据类型是字符型排序规则
默认
字段数据类型
整型
类型 占用空间 存储范围 说明
tinyint 1字节 无符号 0-255 有符号 -128-127 整数 小于255 性别 状态码
smallint 2字节 无符号 0-65535 整数 小于65535
mediumint 3字节 无符号0-16777215 整数 0-16777215
int 4字节 无符号0-4294967296
bigint 8字节 无符号0-18446744073709551616
字符串
类型 占用空间 存储范围 说明
char(M) 字符数3或4 最大值255字符 M表示字符数,最大值255
【定长】【短文本】
占用空间申请后固定,尽管数据量没达到指定长度
varcahr(M) 字符数3或4+L M表示字符数,最大空间65535字节
最大存储的字符数跟编码有关,跟行格式有关
【变长】【短文本】
L用来记录当前字段内容的长度1-2字节
text 文章
longtext 文章
日期类型
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数
类型 说明
date 年月日 4字节 2022-06-02
datetime 年月日时分秒 8字节 2022-06-02 11:21:21
int 占用4字节 时间戳
通常需要额外为每一张创建主键字段表ID【整型、无符号、非空、自增、唯一】
浮点型
xxxxxxxxxxCREATE TABLE students
(stu_id
mediumint(6) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT ‘学生表ID’ ,stu_no
mediumint(6) NOT NULL COMMENT ‘学号’ ,realname
char(4) NOT NULL COMMENT ‘姓名’ ,birthday
date NULL ,sex
char(1) NULL DEFAULT ‘男’ ,sex_2
tinyint(1) NULL DEFAULT 1 COMMENT ‘1表示男生2表示女生’ ,major
varchar(15) NOT NULL ,total_credit
tinyint(1) NULL DEFAULT 0 ,remark
varchar(200) NULL ,balance
float NULL COMMENT ‘余额’ ,balance_2
decimal(10,2) NULL COMMENT ‘余额’ ,PRIMARY KEY (stu_id
),UNIQUE INDEX (stu_no
) )