了 解 p h p 基 本 使 用 , 是 方 便 后 期 理 解 n o d e 的 使 用 , 而 不 是 主 要 技 能 , 前 端 开 发 不 写 这 个 了解php基本使用,是方便后期理解node的使用,而不是主要技能,前端开发不写这个 了解php基本使用,是方便后期理解node的使用,而不是主要技能,前端开发不写这个
服务器小到一台计算机,大到几十万几千万的机房,其实也就是一些计算机群组,存储量更大
** 服务器就是提供各个互联网公司项目的一个平台,所谓项目上线,就是将项目发布到服务器上
** 服务器就是一台主机,也需要操作系统,里面什么软件都没有,需要安装一些环境
** 在开发的时候需要什么环境,到时候主机里面就得配置什么环境
** 在开发中可以不用知道那个主机在哪里,因为可以使用远程连接操控
** 服务器有买的,有租的,有公司直接使用小型的,或者自己做小项目测试的虚拟主机
阿里云、腾讯云、百度云都提供租售服务,不过我们目前可以先不考虑租,因为没有完整的项目,去了公司也由公司统一搞定,
IP地址就像是生活中的地址,比如 德云社北京总部,地址就在 北京市西城区北纬路甲1号
那么某个公司的项目地址,就在网络服务器中的某个位置,例如 192.78.36.52
每个地址都不会重复,都是唯一的,但是这样访问起来很麻烦,因为ip地址记忆起来很麻烦
比较出名的就是新浪网、阿里云都提供域名的租借和购买,价格不等
域名就是为了方便用一个比较好记的单词或者简写形式去对应一个复杂的ip地址
比如上图,baidu.com 对应的就是一个叫做 220.181.57.216 的ip地址
还是拿生活中的场景来说,端口就好像楼层,默认是80层,并且每层的单位还都不一样
网址后面也是有楼层的,或者叫端口,默认是80端口,如果改写了别的端口,那么项目也有完全不同的指向,两个是不同的地方
例如:https://www.baidu.com:80 这是默认的端口,所以当输入完毕之后,:80 这个值会消失
而当输入 https://www.baidu.com:3030 这个端口和上一个端口就指向了不容的区域
http://www.baidu.com:80
https://www.baidu.com:443
数据库 :3306
url是浏览器跟服务器交流的主要方式之一
1,协议 : http:// https:// ftp:// file://
2,域名 : www.baidu.com .cn .org …
3,端口 : 默认80,可以忽略
4,文件 : 默认首页index.html,可以忽略
5,键值 : 通过?开头,然后通过k=v表示,通过&连接
6,锚点值 : #号表示的内容
例如: w a m p l n m p
https://d.weibo.com/item/?topnav=1&mod=logo&wvr=6#first
由于在做案例的时候,会涉及到每天的内容不同,或者每个案例不相同,在设置站点的时候,文件夹也不同,所以如果想将文件夹设置在其他位置,也能实现web容器的情况就可以做出以下设置
选择完毕之后会自动重启,选择好文件夹之后,发现并如果当前没有默认首选项里面的页面则会报错,所以需要再接着设置
选择完毕之后,一定要点击应用
以下设置能够将文件以列表的形式展示
如此设置,就能看到文件以列表形式展示,然后单击某个文件则进行相应的跳转
这里的意思就是说,刚刚随便找了个文件夹,但是打开的方式就变得很复杂了,所以手动设置一下类似于域名的地址,指向那个文件夹,这样,打开的时候,就方便啦
1,配置虚拟主机名称
选择之后,点击确认,自动重启,这个时候发现虽然重启结束了,但是用刚刚的地址访问不了
2, 配置host文件 (一个是快捷方式,一个是直接找)
编辑host文件,可以用记事本或者编辑器打开
这个时候,如果再去通过这个地址去打开页面,发现还是打不开,不过提示的文本发生了变化,这是由于配置的过程还没结束,还需要再进行
3, 配置文件修改参数
注意,这里有个小细节,要修改,还要重启
注意:
当在配置第二个虚拟主机的时候,这一次生成,会把第一次生成的内容替换掉,
也就是最后一步那个添加Index的步骤,要重复操作一下,再重启一下就好了
1, 只有php格式的文件才能解析php的代码,不然会被解析成注释
2, 按照php的格式来写内容
// 在php中,表述输出当前的时间
echo date('Y-m-d');
?>
在php代码内不可以写标签,php的代码可以在标签以内
写完一句加一个分号
1, echo 输出字符串,多个字符串用逗号
// 不识别多个空格
echo "123", "adfdf";
?>
2, print( ) 输出字符串, 只能输出一个值
print("abc")
?>
3,print_r( ) 输出复杂的数据类型
print_r([1, 2, 3])
// 输出: Array([0] => 1 [1] => 2 [2] => 3)
echo [1, 2, 3]
// 输出:Array
?>
4,var_dump( ) 可以输出复杂类型,输出复杂类型的key和value
var_dump(['ab', 'fbb', 'exo'])
// 输出:array(3) { [0] => string(2)'ab' [1] => string(3)'fbb' [2] => string(3)'exo' }
?>
1, php的代码只要不在那一堆尖括号里面,则不会执行,会原样输出
echo "abc" // 原样输出
//...
?>
2,php语法中也是存在多分支语句,也就是if语句
if(true) {
echo '结果为真'
}
?>
if (true) {
?>
// 这句话是在php语法结构以外
<h2>结果为真</h2>
}
?>
// 在php中,注释和js中的都是一样的
// line comment 单行注释
# line comment 单行注释 不推荐使用
/*
block comment 块级注释
*/
** 所有的代码必须都得在php的代码以内
// 变量不需要关键字声明,不过都得加上$开头,区分大小写,其他跟js一样
$age = 20;
echo $age;
$name = 'jack';
/* 如果不赋值,默认是null */
?>
方法 | 功能 |
---|---|
isset( ) | 判断当前变量是否存在,判断变量是否定义了,判断当前的值是否为null |
empty( ) | 判断变量是否为空值 - “” 0 “0” null false array( ) |
unset( ) | 删除变量,可以删除多个,用逗号隔开 |
isset( )
// 如果返回结果为true那么返回 1 如果返回结果为fall,那么返回null
$name = 'abc';
echo isset($age); // 空白
echo '';
echo 123;
var_dump(isset($age)); // boolean(false)
?>
empty( ) 如果为空值就返回true
$name = 'abc';
$num = 0;
echo empty($age);
echo empty($num);
var_dump(empty($num)); // boolean(true)
?>
unset( ) 删除变量
$name = 'abc';
$age = 20;
echo $name;
echo '';
unset($name);
// unset($name, $age)
echo $name;
?>
js中的数据类型主要有以下几种
数据类型 | 解释 |
---|---|
string | 字符串 |
integer | 整型 - 只能是整数 |
float | 浮点型 - 小数 |
boolean | 布尔型 - true或者false |
array | 数组 |
object | 对象 |
NULL | 空 |
PHP可以按照以下方式分成三个种类:
基本数据类型 | 复合数据类型 | 特殊类型 |
---|---|---|
string 字符串 | array 数组 | NULL 空 |
integer 整型 - 只能是整数 | object 对象 | 资源 |
float 浮点型 - 小数 | ||
boolean 布尔型 - true或者false |
检测数据类型的方法:
方法名称 | 功能 |
---|---|
is_string( ) | 判断当前变量是否为字符串类型 |
is_bool( ) | 判断当前变量是否是布尔类型 |
is_int( ) | 判断是否是整型 |
is_float( ) | 判断是否是浮点型 |
is_array( ) | 判断是否为数组类型 |
is_object( ) | 判断当前变量是否是对象类型 |
$name = 'delireba';
$age = 20;
echo is_string($name); // 1
var_dump(is_string($name)); // boolean(true)
var_dump(is_bool($age)); //
?>
在php中,字符串的使用是有区别的 在php中,字符串的拼接使用小数点,而不是使用加号
$name = 'fbb';
echo $name; // fbb
/* 在php中,字符串的拼接使用小数点,而不是使用加号 */
echo '她的名字叫'.$name
?>
单引号的特点
/* 在单引号中有变量的话,单引号无法解析 */
$name = 'yiyang';
echo '我的名字叫$name'; // 我的名字叫$name
// 而且出现单引号嵌套或者斜杠 需要通过斜杠来转义
echo '我的\\名字\'叫$name'; // 我的\名字'叫$name
?>
双引号的特点
/* 在双引号中有变量的话,双引号就会解析 */
$name = "Bluce";
echo "我的名字叫$name"; // 我的名字叫Bluce
// 如果变量后面还有合法字符,则后面的一截都被当变量了
echo "我的名字叫$name我今年20"; // 我的名字 这里把“$name我今年20”整个当变量了,因为没有定义这个变量所以就为空 这里就不显示
// 加上空格就好了
echo "我的名字叫$name 我今年20"; // 我的名字叫Bluce 我今年20
// 推荐
echo "我的名字叫{$name}我今年20"; // 我的名字叫Bluce我今年20
?>
支持的转义字符
\" \\ \n 换行 \t \$
1, HTML里面不能直接写php代码
2, php文件里面可以写html标签,但是php代码里面不能写html
3, php里面负责解析字符串,但是最终执行环境在浏览器
4, 如果混编php和html的话,只要是php的代码就必须要通过标记给包裹起来
数组分为两种类型
通过索引来操作数组
1, array(添加数组的成员, 成员类型不限)
$arr = array(1, 2, 3, true, "abc");
// 通过索引取值
echo $arr[4]; // "abc"
echo $arr[3]; // 本来应该是true,但是输出了1
// php中遍历数组
// 在php中小数点是拼接字符的意思 这里的length调用错误
/* for($i = 0; $i < $arr.length; $i++) { */
// 使用count方法能够计算当前数组的长度
for($i = 0; $i < count($arr); $i++) {
// 打印每一项的值
echo $arr[$i]." "; // 使内容之间有些距离
}
print_r($arr);
/*
Array(
[0] => 1
[1] => 2
[3] => 3
[4] => 1
[5] => abc
)
*/
?>
2,中括号的方式,[ ]
与上面没有太大的差异
以键值对的方式描述数据,类似于js中的字面量对象
// 语法: array($key => $value, $key => $value)
$arr = array (
"name" => "yiyang",
"age" => 20,
"gender" => true
);
echo $arr["gender"]; // 1
// 打印数组,使用print_r( )的方法
print_r($arr);
/*
Array(
[name] => yiyang
[age] => 20
[gender] => 1
)
*/
/* 遍历关联数组的方法 */
/*
foreach(数组对象 as 键 => 值) {
...
}
*/
foreach($arr as $key => $value) {
echo $key . ":" . $value . "";
}
/* => 输出
name:yiyang
age:20
gender:1
*/
// 简洁语法
foreach($arr as $value) {
echo $value . "";
}
?>
** 所有的数组本质上都是关联数组, foreach方法也可以操作索引数组;
** 如果通过空的中括号赋值,会自动追加和排序,还会变成混合数组
count( ) 计算数组的长度length
unset( ) 使用数组删除某一项会有一点点小问题
$arr = [1, 2, 3, 4, 5];
print_r($arr);
unset($arr[2])
echo '
';
print_r($arr);
/*
之前: Array([0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5)
现在: Array([0] => 1 [1] => 2 [3] => 4 [4] => 5)
*/
// 索引和值都没有,变成了稀疏的了
?>
/* $arr = array(
1, 2, 3,
"name" => "tylor",
array()
); */
// 描述学生对象
$arr = array(
// 描述第一个学生对象的数据
"name"=>array(
"name" => "tylor",
"age" => 20
),
array(
"name" => "Bluce",
"age" => 18
)
);
print_r($arr);
/* Array(
[0] => Array(
[name] => tylor
[age] => 20
)
[1] => Array(
[name] => Bluce
[age] => 18
)
)
*/
// 通过嵌套循环输出当前的数组
foreach($arr as $key => $value) {
// 二维数组的遍历
// print_r($value); 两个内层数组
foreach($value as $subkey => $subvalue) {
echo $subkey . ":" . $subvalue . "
";
}
}
/* ==> 输出
name:tylor
age:20
name:Bluce
age:18
*/
?>
主要分为两种,自动转换和强制类型转换,也就是显式转换和隐式转换,自动转换用的多
bool( ) string( ) object( )
$str = '123';
var_dump($str); // string(3) '123'
var_dump((int)$str); // int(123)
echo '
';
// 转换成数组
var_dump((array)$str); // Array {[0] => string(3) '123'}
$abc = 'jackey';
$num = (int)$abc;
var_dump($num); // int(0)
?>
+号只能是运算符,系统默认会隐式转换成数值,如果转换不了,就会给一个默认值
默认值类型
数据类型 | 默认值 |
---|---|
int | 0 |
object | null |
bool | false |
float | 0.0 |
在php中,拼接的运算符,是小数点.
运算符类型
算术运算符 | 赋值运算符 | 逻辑运算符 | 比较运算符 |
---|---|---|---|
+ 加 - 减 * 乘 / 除 | = 一般赋值 | !取反 | > 大于 < 小于 |
% 求余,相除完剩余的结果 | += 在本身追加 | && 与,严格要求 | >= 大于等于 <=小于等于 |
++ 自加单独没区别 | -= 在本身扣除 | || 或,满足一项 | == 是否相等 === 是否全等 |
– 同上 | *= /= 同上逻辑 | != 不相等 !== 不全等 |
三元运算符 表达式会返回true或者false ? 如果为true返回值1 : 如果为false返回值2
顺序结构 => 流程控制 => 循环
$age = 40;
if($age > 18) {
echo '您已成年';
} else {
echo '您未成年';
}
// 简写
if($age > 10) :
echo '您已成年';
else :
echo '您未成年';
endif;
/*
if():
elseif():
elseif():
else:
endif;
*/
?>
// 正常循环
for($i = 0; $i < 10; $i++) {
// 输出语句
}
// 指令式循环
for($i = 0; $i < 10; $i++) :
// 输出语句
endfor;
?>
习惯使然,没有什么强制要求;
// 函数声明
function getSum($num) {
$sum = 0;
for($i = 0; $i <= $num; $i++) {
$sum += $i
}
return $sum;
}
echo getSum(100);
/*
!!!!! 在函数中没有作用域链,访问不到外部的变量值,
如果找不到当前变量或者当前变量没有赋值,则转换为int类型就是0,
如果确实需要访问外部数据,可以使用global,添加对外部成员的引用
*/
$num = 200;
function getNum() {
// 添加到全局中
global $num;// 引用的同时不能赋值
$num=10;
echo $num;
}
getNum();
?>
超全局变量名称 | 作用 |
---|---|
$GLOBALS | 引用全局作用域中可用的全部变量 |
$_SERVER | 获取服务端相关信息 |
$_REQUEST | 获取提交参数 |
$_POST | 获取post提交参数 |
$_GET | 获取get提交参数 |
$_FILES | 获取上传文件 |
$_ENV | 操作环境变量 |
$_COOKIE | 操作cookie |
$_SESSION | 操作session |
$name = 'jack Ma';
$age = 40;
function test() {
// echo $GLOBALS;
print_r($GLOBALS)
}
test();
/*
Array(
[_GET] => Array()
[_POST] => Array()
[_COOKIE] => Array()
[_FILES] => Array()
[GLOBALS] => Array
* RECURSION(递归) *
[name] => jack Ma
[age] => 40
)
*/
?>
// !!!定义说明 不可修改,区分大小写,一般用大写
// define(name, value, insensitive); insensitive -> 不敏感,迟钝的
define("PI", 3.14, false); // 设置为true则代表不区分大小写
echo PI; // 3.14
?>
预设常量(魔术常量)
在不同的使用场景下,代表不同的值
常量名称 | 作用 |
---|---|
_LINE_ | 可以获取当前的代码行 |
_FILE_ | 可以获取当前文件的路径 目录+文件名 |
_DIR_ | 可以获取当前文件的目录 |
_FUNCTION_ | 可以获取当前魔术常量所在的函数 |
09
10
11 echo __LINE__; // 11 返回当前的行号
12 ?>
13
说明: 在一个文件中引入另外一个文件的方法
html,css都有类似的方法,但是javascript不行,所以才有了后期的模块化
01-constant.php 用来描述一些固定的信息
define("__SCHOOL_NAME", "传智播客");
define("__ADDRESS__", "首都北京");
echo "下面是被入的代码块";
?>
02-require.php 用来载入上面的文件
// include 相当于在这里复制粘贴了一份
include 'constant.php';
echo SCHOOL_NAME; // 传智播客
// include_once 只会载入一次
include_once 'constant.php'; //
echo SCHOOL_NAME; // 传智播客
// require
require 'constant.php';
echo SCHOOL_NAME; // 传智播客
// require_once
require_once 'constant.php';
echo SCHOOL_NAME; // 传智播客
?>
require | require_once | include | include_once | |
---|---|---|---|---|
载入文件不存在是否影响后续代码执行 | 会 | 会 | 不会 | 不会 |
多次调用是否重复执行被载入的文件 | 会 | 不会 | 会 | 不会 |
总结:
这里的api指的就是一些方法,或者内置函数
方法 | 作用 |
---|---|
strlen( ) | 获取字符串的长度 |
mb_strlen( ) | 没有设置编码,就使用php默认的编码 |
mb_internal_encoding( ) | 获取php内部默认的编码 |
strlen( )
$str = "hello world";
// 获取字符串的长度
// 无法正确处理中文字符(宽字符集:php默认不支持的字符-中文、韩文、日文)
echo strlen($str); // 11 加两个中文就变17 一个中文3个字节
?>
// 获取函数内部默认的编码
echo mb_internal_encoding(); // UTF-8
?>
mb_strlen( )
$str = "hello world你好";
// 没有变化就使用默认编码
// 默认不能使用,如果想使用,就需要添加一个引用
echo mb_strlen($str); // 13
?>
解开注释掉的那个引用
使用搜索查找到当前那个位置, 选择记事本打开,按住ctrl+f查找
去掉前面的分号,!!!!!一定要记得手动重启一下服务器;
备注:只有php5.6版本以上才支持,切换后点击应用
方法 | 名词 | 释义 |
---|---|---|
time( ) | 时间戳 | 从Unix纪元(格林威治 1970-01-01 00:00:00)到现在的秒数 |
date( ) | 格式化日期 | date(“Y-m-d H:i:s”) 或者 date(“Y-m-d H-i-s”, $time) |
strtotime( ) | 转换时间为秒数 | 把日期格式转换为秒数的时间戳 |
// 输出从1970-1-1 00:00:00到现在的秒数
echo time();// 1520697202
echo date('Y-m-d H:i:s'); // 2018-11-12 05-14-52
// !!!! 这里的时间与正常时间不同,有8个小时的误差
?>
修改配置文件
搜索timezone
点击查找下一个,找到属于这个开头的
!!!!手动重启服务器
strtotime( )
echo strtotime("1970-1-2 00:00:00"); // 57600
?>
方法 | 功能 | PHP |
---|---|---|
file_get_contents( ) | 将文件读入字符串 | 4 |
file_put_contents( ) | 将文件写入字符串 | 5 |
// 设置当前页面的返回值是图片类型
header("Content-Type:image/jpg");
// file_get_contents( )
// 读取文件成功,返回一个字符串类型的值, 如果失败,返回false
$res = file_get_contents('data.text');
var_dump($res); // bool(false)
/*
1, 读取任意类型的文件
2, 如果读取图片,要在最前面加上一句代码
header("Content-Type:image/jpg");
*/
$res1 = file_get_contents("./images/monkey.png");
echo $res1;
?>
// file_put_contents(文件路径, 需要写入的内容) 指定的内容写入文件,同时返回字符的长度
file_put_contents("data.txt", "这是我写入的内容"); // 24
// 上一种写法会覆盖之前原本的内容
// 需要加入一个参数 FILE_APPEND
file_put_contents("data.txt", "这是我写入的内容", FILE_APPEND);
?>
静态网页生成:
1,在html文件中写入结构,
2,在css文件中写入样式
3,在js中完成页面基本效果
4,双击在浏览器中浏览网页
使用php将网页修改为动态网站:
1,将html文件修改为php格式
2,将主体的规律的数据,规律的存储到php语法的数组中
3,使用php中的遍历,得到数组中每一项的数据
4,生成页面结构,打印到页面中
5,通过ip地址访问当前的网页
使用html书写的静态页面结构
<ul>
<li>
<img src="img/banana1.jpg" alt="">
<a href="#">香蕉a>
li>
<li>
<img src="img/apple1.jpg" alt="">
<a href="#">苹果a>
li>
<li>
<img src="img/orange1.jpg" alt="">
<a href="#">橘子a>
li>
...
ul>
// 将图片的路径和a链接的内容整理到数组中
$arr = array(
array(
"src" => "img/banana1.jpg",
"name" => "香蕉"
),
array(
"src" => "img/apple.jpg",
"name" => "苹果"
),
array(
"src" => "img/orange.jpg",
"name" => "橘子"
)
//...
)
?>
foreach($arr as $value) {
?>
<li>
<img src="$value['src'] ?>" alt="" />
<a href="#"> echo $value['name'] ?></a>
</li>
} ?>
// 新建 get_data.php 文件
/*
1, 如果还是直接用数组存起来,那么与上面的内容则无异
2, 而以后究竟以什么形式传入,或者传入的内容是什么方式补丁
3, 假设传入的方式为字符串,如何拆解想要的信息,映射到数组中
*/
$str = "img/pineapple1.jpg|菠萝";
// ??? 如果是在php中该如何处理
// 使用 explode( ) 方法
// print_r(explode("|", $str)); Array([0] => img/pineapple1.jpg [1] => 菠萝)
$value = explode("|", $str);
?>
如果使用javascript可以依照如下代码结构
<script>
var str = "img/pineapple1.jpg|菠萝";
console.log(str.split("|"));
// ["img/pineapple1.jpg", "菠萝"]
script>
$str = "img/pineapple1.jpg|菠萝";
$value = explode("|", $str);
// ["img/pineapple1.jpg", "菠萝"]
?>
<li>
<img src="$value[0] ?>" alt="" />
<a href="#"> echo $value[1] ?></a>
</li>
新建一个 data.txt 文件存入数据
img/pineapple1.jpg|菠萝
在php文件中引入数据
// !!!! 在这里引入了数据文件
$str = file_get_contents("data.txt");
$value = explode("|", $str);
?>
<li>
<img src="$value['src'] ?>" alt="" />
<a href="#"> echo $value['name'] ?></a>
</li>
img/pineapple1.jpg|菠萝
img/orange1.jpg|橘子
// 引入文件
$str = file_get_contents("fruit.txt");
// 拆分每一行数据
// print_r(explode("\n", $str));
/*
Array(
[0] => img/pineapple1.jpg|菠萝
[1] => img/orange1.jpg|橘子
)
*/
$arr = explode("\n", $str);
foreach($arr as $value) {
// 继续拆分得到的每一行字符串
$result[] = explode("|", $value);
}
// print_r($result); 能够得到最终的数组
foreach($result as $value) {
?>
<li>
<img src="$value[1] ?>" alt="" />
<a href="#"> echo $value[2] ?></a>
</li>
}
?>
在文件结构首页引入php功能的文件
include 'getList.php';
?>
引入最终的完整的txt文档,改变内层拆分的索引
###1.php标记
#2、输出内容的方式
echo:输出多个字符串
print:输出一个字符串值
print_r:可以输出复杂数据类型,如数组,以键值对的形式输出
var_dump:可以输出复杂数据类型,如数组,以键值对的形式输出,还可以输出数据的长度
'':不能解析变量,会将变量当成普通字符串处理 \\ \'
"":能解析变量 \" \t \n \r \$
###4.数组:
创建方式:
$arr = array()
$arr = []
$arr[] = value; //如果数组不存在则可以自动的创建一个数组,并将当前值添加到数组中,如果存在则添加数据到数组
数组的类型:
索引数组:不人为设置key $arr = array(1,2,3,4);
关联数组:人为设置key和value $arr = array("name"=>"jack")
混合数组:$arr= array(1,2,3,"name"=>"jack",4)
二维数组:数据的值本身又是一个数组
$arr = array(
array(
"name"=>"jack",
"age"=>20
),
array()
);
数组遍历:for | foreach
for($i =0;$i $value){}
###5.变量作用域:函数内部默认不能使用函数外部所声明的成员,如果想使用,则:
1.使用global关键字
2.使用超全局变量$GLOBALS
###6.常量的定义和使用:
define(名称,值,false)
###7.载入其它文件:文件包含
include:如果载入失败,不会报错,后续代码会继续执行,它可以重复载入
include_once:如果载入失败,不会报错,后续代码会继续执行,它不会重复载入,只会真正的载入一次
require:如果载入失败,会报错,后续代码不会继续执行,它可以重复载入
require_once:如果载入失败,会报错,后续代码不会继续执行,它不可以重复载入
###8.常用API
文件操作:
file_get_contents:可以读取文件内容并返回
file_put_contents(文件路径,写入的内容,FILE_APPEND):可以将指定的字符串内容写入到文件,其中第三个参数FILE_APPEND可以实现文件内容的追加
###9.html混编
1.在
2.在结构的代码会原样输出
3.混编实现方式
1.' ?>
2.
浏览器向线上服务器请求获取资源的一种方式。
1.1.1 正常请求资源的方式
1.1.2 通过事件发起的请求
get请求在发起的时候有格式,在发起时会携带很多的参数
例如: http://tieba.baidu.com/f?ie=utf-8&fr=bks0000&kw=迪丽热巴&red_tag=y2377671083
1.1.3 get请求方式的特点
1,get方式在url后面拼接参数,只能以文本的形式传递数据
2,传递的数据很小,4KB左右(不同的浏览器有略微差异)
3,安全性低,因为在发起请求的时候会显示在地址栏
4,速度快,对于安全性要求不高的请求来说
1.2.1 post请求方式
post指的是提交数据,一般发送存储,类似于张三给李四邮寄一份礼物;
通常会通过form表单内的元素收集好数据之后进行提交和上传,不过必须要在form的method属性中写明提交的方式,不然默认是以get方式
1.2.2 post请求提交的特点
1,post方式安全性较高,不过也有可能被抓包,所以后期需要其他的加密形式
2,传递数据量大,请求数据没有长度的要求,上限默认为8M,可以在配置文件中修改
3,请求不会被缓存,也不会保留在浏览器历史记录中
使用场景:
密码等安全性要求比较高的时候,提交的数据量比较大:发布文章、游记、上传文件;
创建form-get.php文件
jack [userPwd] => 123)
echo '我的名称是'.$_GET['userName123'].', 我的密码是'.$_GET['userPwd'];
?>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<form action="form-get.php" method="get">
用户名: <input type="text" name="userName"> <br>
密码: <input type="password" name="passWord"> <br>
<input type="submit"> <br>
form>
body>
html>
从列表页,点击跳转到详情页
final.php => 最终展示页面
getList.php => 操作和渲染数据页面
detail.php => 详情页面
在getList.php操作和渲染数据页面的时候,给a链接添加跳转页面的地址和动态id
...
foreach($result as $value) {
?>
<li>
<img src="$value[1] ?>" alt="" />
<a href="./detail.php?id=$value[0] ?>"> echo $value[2] ?></a>
</li>
}
?>
在页面最顶部使用$_GET接收参数
$id = $_GET["id"]; // 接收id号
// 读取文件
$str = file_get_contents("fruit.txt");
$arr = explode("\n", $str);
// 遍历数组,再次分割
foreach($arr as $key => $value) {
// 以名称中括号的方式,如果数组不存在就先创建数组,如果存在就直接追加
$result[] = explode("|", $value);
}
// 遍历,查找对应商品号的商品
foreach($result as $value) {
// 如果id号对应,则查找到对应商品
if($id == $value[0]) {
// 将查找的结果,存储到一个新的变量
$data = $value;
break;
}
}
// print_r($data)
?>
替换结构部分
<li>
<img src="$data[1] ?>" alt="" />
<p> echo $data[2] ?></p>
</li>
需要将form表单中的属性更改,将method属性设置为post,将action属性改变地址
当前的文件名称为 form-post.php
<form action="form-post.php" method="post">
用户名: <input type="text"> <br>
密码: <input type="password"> <br>
<input type="submit"> <br>
form>
在当前文件的最顶部用 $_POST来接收发送的值
// !!! 判断当前用户是否发送了请求, 是否是以post方式
// print_r($_SERVER); 很大一串关联数组, REQUEST_METHOD
if($_SERVER['REQUEST_METHOD'] === 'POST') {
echo '我的名称是'.$_POST['userName123'].', 我的密码是'.$_POST['userPwd'];
}
?>
_$REQUEST 这个能接收到get或者post两者任何一种方式提交的数据
** 效率低下,受配置文件的影响,不怎么推荐使用
get | post | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交) |
书签 | 可收藏为标签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码 |
历史 | 参数保留在浏览器历史中 | 参数不会保存在浏览器历史中 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符) | 无限制 |
对数据类型的限制 | 只允许 ASCII 字符 | 没有限制。也允许二进制数据 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分,在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中 |
可见性 | 数据在 URL 中对所有人都是可见的 | 数据不会显示在 URL 中 |
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
在文件的顶部书写php代码
print_r($_GET); // 不管在怎么选择, 但是gender始终是on
// Array([userName] => jack [userPwd] => 123 [gender] => on)
/* ==> 单选框
系统会自动的收集当前表单元素的value值
解决办法: 给单选按钮添加value值,区分一下
*/
/* ==> 复选框
如果复选框的名称一样,那么就会默认传递最后一个选项的值
如果需要传入所有选中的复选框的数据,可以在name属性值后面添加[]
添加了[], 在收集数据的时候,就会把他们放进一个数组内
eg:
爱好: 写代码
看书
*/
?>
文件上传遵循的流程:
选取文件提交 ==> 存入服务器暂存区 ==> 有后续操作后存入到服务器
// !!! 在php中文件上传必须得是post请求
/*
1, 必须给表单设置enctype属性
application/x-www-form-unlencoded 将参数编码为键值对的格式,标准格式
(UTF-8 GBK GB2312) 用来处理字符串,默认的编码格式
multipart/form-data 专门用来处理特殊文件,比如文件
*/
<form action= echo $_SERVER['PHP_SELF'] ?> method="post" enctype="multipart/form-data">
文件选择: <input type="file" name="myFile"> <br>
<input type="submit">
</form>
// 在php中,上传之后的相关信息都存储在 $_FILES 超全局变量中
print_r($_FILES)
/*
Array(
[myFile] => Array(
[name] => xxx.jpg (源文件的名称)
[type] => image/png (源文件的类型)
[tmp_name] => C:\windows\phpE412.tmp (保存文件的路径)
[error] => 0
[size] => 256436
)
)
*/
// 使用一个方法来实现文件的移动,否则文件将在程序结束后被自动遗弃
// move_uploaded_file(源文件的全路径, 目标文件的全路径)
// 文件夹是手动创建的
move_uploaded_file($_FILES["myFile"]["tmp_name"], "./upload/temp.png")
?>
由于发送的是post请求,结果文件一打开的时候就开始了一些操作,发现报错了
所以,在打开文件的时候,还得需要一些判断
// 判断当前的数组是否为空,为空则不进入
if(!empty($_FILES)) {
move_uploaded_file($_FILES["myFile"]["tmp_name"], "./upload/temp.png")
}
?>
// !!!通过表单元素的属性,限制文件上传的格式
// 1, 在表单元素中可以限制
<input type="file" accept=".jpg,.png" />
// 2, 在后端进行判断
if(!empty($_FILES)) {
$type = $_FILES["myFile"]["type"];
// ***** strpos(源字符,搜索字符) 可以获取指定字符串在源字符中第一次出现的索引
if(strpos($type, "image/") === 0) {
move_uploaded_file($_FILES["myFile"]["tmp_name"], "./upload/temp.png");
}else {
echo "您选择的不是一张图片";
}
}
?>
文件名称不固定,设置合理的文件名称
// 获取当前文件的名称
$fileName = $_FILES["myFile"]["name"];
// 拼接文件的名称
// move_uploaded_file($_FILES["myFile"]["tmp_name"], "./upload/".$fileName);
// ???? 如果两次都是一次名字,很有可能重名,然后会覆盖之前的文件
// 生成随机数,时间是唯一的
// $myname = time();
// strrchr(源字符串,指定搜索的字符串)
$extension = strrchr($fileName, "."); // 如果是 demo.png , 就能获取到后面的 .png
$myname = time().rand(1000, 9999).$extension; // 得到一个随机的唯一的值, 还带扩展名
?>
方法 | 作用 | 示例 |
---|---|---|
move_uploaded_file( ) | 移动文件 | move_uploaded_file(文件存储位置, “路径”) |
strpos(源字符, str) | 搜索字符在源字符第1次出现的索引,数值 | strpos($type, “image/”) |
strrchr(aa, “.”) | 获取当前符号右侧所有的字符串 | strrchr($fileName, “.”) |
rand(1000, 9999) | 获取随机数 |
当上传的文件比较大的时候,会出不来想要的效果
而此时,得到的$_FILES数组中,error指向的值为1
根据查询手册得知,这里的意思指的是,上传的文件超出了大小
如果需要修改大小的范围,需要修改配置文件
搜索相关的信息
得到对应的位置之后,发现默认为2M的大小
修改完毕之后,一定要记得重启服务器!!!
服务器对每一次post请求传递做了限制,默认为8M
可以修改配置文件,改大对应的值,搜索post_max_size
在文件中搜索
找到位置后,该变原有的大小
同时上传多个文件
<input type="file" name="myfile" multiple>
_1.0 如果需要后端服务器的 $FILES 接收多个文件,则需要在name属性值后面加上[ ]
<input type="file" name="myfile[]" multiple>
2.0 实现完成效果
/*
Array(
[myfile] => Array(
[name] => Array(
[0] => 11.png
[1] => 111222.jpg
)
[tmp_name] => Array(
[0] => C:\Windows\phpc51.tmp
[1] => C:\Windows\phpc62.tmp
)
)
)
*/
if(!empty($_FILES)) {
// 获取扩展名的数组
$nameArr = $_FILES["myfile"]["name"];
$pathArr = $_FILES["myfile"]["tmp_name"];
foreach($pathArr as $key => $value) {
// 获取唯一的图片名称
$name = time().rand(1000, 9999).strrchr($nameArr[$key], ".");
// 将文件存储到永久目录 move_upload_file
move_upload_file($value, "./upload/".$name);
}
}
?>
综合性案例
直接使用写好的结构代码进行修改
将静态的文件修改为动态的文件
<form action="$_SERVER["PHP_SELF"] ?>" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="username">
昵称:<input type="text" name="nickname">
年龄:<input type="text" name="age">
电话:<input type="text" name="tel">
性别:<input type="radio" name="gender" value="男" checked>男
<input type="radio" name="gender" value="女" >女
<br>
班级:<select name="class" >
<option value="1">黑马1期</option>
<option value="2">黑马2期</option>
<option value="3">黑马3期</option>
</select>
头像: <input type="file" name="photo" >
<input type="submit" value="添加信息">
</form>
if($_SERVER["REQUEST_METHOD"] == "POST") {
print_r($_POST);
}
?>
if($_SERVER["REQUEST_METHOD"] == "POST") {
// 判断当前用户是否输入了用户名 或者 填入的是否为一个空字符串
if(!isset($_POST["username"]) || $_POST["username"] === "") {
echo "请输入姓名";
return;
}
}
?>
由于当前的return会结束整个php文件,修改后变成如下情况
// 使用函数声明
function register() {
// 判断当前用户是否输入了用户名 或者 填入的是否为一个空字符串
if(!isset($_POST["username"]) || $_POST["username"] === "") {
echo "请输入姓名";
return;
}
if(!isset($_POST["nickname"]) || $_POST["nickname"] === "") {
echo "请输入昵称";
return;
}
}
if($_SERVER["REQUEST_METHOD"] == "POST") {
register();
}
// 去掉空格
// trim($_POST["username"])
?>
明确数据的格式,在txt文档中,按照竖直线和换行分割
方法 | 作用 |
---|---|
implode( ) | 将数组以某个分割符进行拼接,返回一个字符串 |
explode(”|“, $str) | 将字符串以某个符号进行分割,返回一个数组 |
// 使用函数声明
function register() {
// 判断当前用户是否输入了用户名 或者 填入的是否为一个空字符串
if(!isset($_POST["username"]) || trim($_POST["username"]) === "") {
echo "请输入姓名";
return;
}
if(!isset($_POST["nickname"]) || trim($_POST["nickname"]) === "") {
echo "请输入昵称";
return;
}
$str = implode($_POST, "|");
echo $str;
}
if($_SERVER[REQUEST_METHOD] == "post") {
register();
}
?>
实现图片的上传操作
// 判断图片上传操作是否成功
if(empty($_FILES) || $_FILES["photo"]["error"] != 0) {
echo '图片上传失败';
return;
}
// 图片上传成功,需要获取上传成功之后的图片名称
$picName = $_FILES["photo"]["name"];
$ext = strrchr($picName, '.');
$finaName = time().rand(1000, 9999).$ext;
// 将这个文件名添加到 $_POST中
$POST[] = $finaName;
$str = implode($_POST, "|");
// !!! 最后一步,将数据写入到文件
file_put_contents("data.txt", $str."\n", FILE_APPEND);
?>
了 解 h t t p 的 请 求 , 有 助 于 我 们 更 加 清 楚 页 面 请 求 和 相 应 的 过 程 到 底 发 生 了 什 么 了解http的请求,有助于我们更加清楚页面请求和相应的过程到底发生了什么 了解http的请求,有助于我们更加清楚页面请求和相应的过程到底发生了什么
关于协议
对于应用层开发人员,接触最多的网络协议通常都是传输层的TCP,为什么这么说,因为再往上的应用层协议,如:HTTP、HTTPS、POP3、SMTP、RPC、FTP、TELNET等等都是基于TCP传输层协议。但对于IP协议,对于应用程序员来说更多的印象还是IP地址这个东西,实际上IP协议是位于TCP协议之下的网络层,对于应用层程序员来说很难直接接触
IP协议 : IP的责任就是把数据从源传送到目的地。它不负责保证传送可靠性,流控制,包顺序和其它对于主机到主机协议来说很普通的服务
TCP协议:TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议
HTTP协议:HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口
在我们获得页面数据之前,客户端需要与服务器端进行三次握手的"问候"
简单来说:
1, 客户端向服务器发起问候,携带编号number
2, 服务器如果收到客户端的问候,回复问候,携带其他编号number
3,客户端确认连接成功,回复服务器收到返回的数据
为什么是3次握手?
这个问题的本质是, 通信不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值
已失效的连接请求报文段的产生在这样一种情况下:
在结束协议的连接之后,客户端向服务器正式发起请求
发起请求的时候,需要具体介绍当前的请求情况,方便服务器做出快速响应
请求报文包含 请求行–请求头–请求体
请求方式 + 空格 + 请求路径 + 空格 + HTTP协议版本
=> GET /demo.php HTTP/1.1
键 | 值 |
---|---|
Host | 请求的主机 |
Cache-Control | 控制缓存(例如:max-age=60 缓存60秒) |
Accept | 客户端想要接收的文档类型,逗号分隔 |
User-Agent | 标识什么客户端帮你发送的这次请求 |
Referer | 这次请求的来源 |
Accept-Encoding | 可以接受的压缩编码 |
Cookie | 客户端本地的小票信息 |
客户端需要向服务端发送的内容
get请求没有请求体,因为都在url的问号后面
如果上传文件的话
响应体一般来说是HTML,也可以是css或者javascript
注意:返回什么类型文件,就修改响应头里的响应类型
虽然要请求的是css文件,但是link的是php文件
由于php是后台文件,最终是在php中返回内容给浏览器,并且可以设置当前的文件类型
<link rel="stylesheet" href="css.php" />
在css.php中书写的代码
// 设置响应头的类型
header("Content-Type:text/css;charset=utf-8;");
echo "body{background:red;}";
?>
页面跳转
<a href="data.php">点击重定向a>
在data.php中完成跳转
// 立马做出跳转
// header("Location:01-getsmt.php");
// 在指定的时间之后跳转
header("refresh:3;url=01-getsmt.php");
?>
// 实现当前页面的自动下载
header("Content-Type:application/octet-stream");
// 指定文件名称, 自动下载,设置下载名称
header("Content-Disposition:attachment;filename=tmp.php");
?>
// 获取请求报文数据
// print_r(getallheaders());
$refer = getallheaders()["Referer"];
echo $referer; // http:127.0.0.1/day04/03-test.html
// 获取url中各个部分的值
print_r(parse_url($referer));
/*
Array(
[scheme] => http
[host] => 127.0.0.1
[path] => /day04/03-test.html
)
*/
?>
客户端打开与服务器的连接发出请求到服务器响应客户端请求的全过程称之为会话
HTTP协议,本来是进行共享多个计算机之间的文件而产生的文件传输协议
而请求的时候,服务器没有记录当前的信息
就比如,去火车站取票,刷身份证拿到票之后,整个会话结束,不会有任何记录
==============
动态网站的出现,表单提交,购物车的DOM操作,付款的跳转…
有了交互的需要,需要携带一些数据在不同页面之间跳转,无凭无据的,可如何是好
cookie是一个文件,用来存储当前的一些信息和服务器保持交流
在前端介绍的sessionStorage和localStorage也是类似的功能
内容 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 一般由服务器生成,可设置失效的时间,如果在浏览器端生成cookie,默认关闭浏览器后失效 | 除非被删除,否则永久保存 | 仅在当前会话下有效,关闭页面或者浏览器后被删除 |
数据大小 | 4k | 20M | 5M |
与服务器端通信 | 携带在http请求头中,若保存cookie过多数据会带来性能问题 | 仅在客户端即浏览器中保存,不参与和服务器的通信 | 仅在客户端即浏览器中保存,不参与和服务器的通信 |
易用性 | 需要程序员自己封装 | 原生接口可以接受,亦可以再次封装来对obj和Arr有更好的支持 | 原生接口可以接受,亦可以再次封装来对obj和Arr有更好的支持 |
// 创建cookie
// setcookie("username", "tylor"); // 可以在请求头中查看
// 判断是否拥有某个指定名称的cookie值 -- $_COOKIE
if(isset($_COOKIE["username"])) {
echo "欢迎回来,朕的小仙女";
}else {
echo "大人头一回来,是打尖儿还是住店呀~";
setcookie("username", "tylor");
}
?>
chrome: 设置 => 更多设置 => 内容设置 => cookie
可以看到明文存储的cookie设置的值;
cookie的有效期
// 时间是秒, 时间参照php的默认起始时间(1970-1-1)
// setcookie("username", "tylor", 100);
setcookie("username", "tylor", time() + 10);
// 设置永久的时间
setcookie("username", "tylor", PHP_INT_MAX);
?>
cookie的有效目录
// 在不同的文件夹输出cookie中的键
echo $_COOKIE["username"];
// 通过path可以设置访问权限,参照网站根目录
setcookie("username", "tylor", PHP_INT_MAX, "/day05/down");
// 设置父级目录,子目录可以访问,设置子目录,上层不能访问 "/" 代表整站可以访问
// Domain: 域名 path: 路径 secure:只有在https这类安全的协议下才会发送
// 某网站中显示的cookie
// set-cookie: ds_user_id=3265153328; Domain=.instagram.com; expires=Wed, 13-Feb-2019 14:19:35 GMT; Max-Age=7776000; Path=/; Secure
?>
// 处理删除cookie的php文件
// 1.0 怎么创建的就怎么删除的
// setcookie("username", ""); 如果开始不是这样设置的,这样删除就不行
setcookie("username", "", PHP_INT_MAX, "/day05/down");
echo "ok";
// 2.0 设置一个过期时间,也是可以删除的
?>
使用写好的表单文件, 在头部判断是否为post提交
function login() {
// 验证用户数据是否合法
if(!isset($_POST["username"]) || trim($_POST["username"]) === "") {
$GLOBALS["error"] = "请输入用户名";
return;
}
if(!isset($_POST["password"]) || trim($_POST["password"]) === "") {
$GLOBALS["error"] = "请输入密码";
return;
}
// 接收用户数据
$username = $_POST["username"];
$password = $_POST["password"];
// 读取文件,进行相应判断
$dataArr = json_decode(file_get_contents("users.json"), true);
foreach($dataArr as $value) {
// 如果下面的条件满足,说明至少用户名是正确的
if($value["username"] == $username) {
$user = $value;
break;
}
}
// 如果这里没有值,告诉用户用户名不存在
if(!isset($user)) {
$GLOBALS["error"] = "用户名不存在";
return;
}
// 能走到这里来,证明$user已经拿到了用户的值
if($user["password"] != $password) {
$GLOBALS["error"] = "密码输入错误";
return;
}
// 匹配成功跳转至主页,否则回到登录页
// !!!!! 将登陆成功的数据,写入到cookie中
setcookie("isLogin", true);
header("Location:./main.php");
}
// 判断是否为post提交
if($_SERVER["REQUEST_METHOD"] === "POST") {
login();
}
?>
// 判断当前有没有定义全局成员
if(isset($GLOBALS["error"])) {
?>
<div class="alert alert-danger" role="alert"> echo $GLOBALS["error"] ?></div>
}
?>
在跳转的首页去判断用户是否之前登录过
// 约定好判断的名字是什么
if($_COOKIE["isLogin"] != true) {
header("Location:login.php");
}
?>
在点击退出登录的页面中,设置跳转到logout.php文件,在此文件中处理删除
// 在删除cookie的时候,要注意它是怎么添加的
setcookie("isLogin", "");
// 回去登录页面
header("Location:login.php");
?>
JSON数据格式目前是使用的最多的,用来传递大量数据的文件
[
{
"title" : "《毒液》",
"director" : "tylor swift",
"actors" : "Kobe Bryent",
"time" : "2020-12-12",
"src" : "./upload/xxx.avi"
},
{
"title" : "《觉醒》",
"director" : "王家卫",
"actors" : "Lebron james",
"time" : "2019-1-14",
"src" : "./upload/xxx.avi"
}
]
// 要使用JSON里面的数据,首先要去读取数据
$str = file_get_contents("movie.json");
echo $str;
// 这里见到的数组其实是个字符串
/*
[
{
"title" : "《毒液》",
"director" : "tylor swift",
"actors" : "Kobe Bryent",
"time" : "2020-12-12",
"src" : "./upload/xxx.avi"
},
{
"title" : "《觉醒》",
"director" : "王家卫",
"actors" : "Lebron james",
"time" : "2019-1-14",
"src" : "./upload/xxx.avi"
}
]
*/
// 读取出的数据,需要转换为最终需要的数据 数组
// !!! json_encode()
// 可以将php数组或者对象转换为json格式的字符串
// !!! json_decode()
/* 可以将json格式的字符串转换为数组或者对象,
- 如果发现json格式的数组以中括号包裹,就可以将字符串转换为数组
- 如果发现json格式的数组以大括号包裹,就可以将字符串转换为对象
*/
$arr = json_decode($str);
print_r($arr);
/*
Array(
[0] => stdclass object (
[title] => 《毒液》,
[director] => tylor swift,
[actors] => Kobe Bryent,
[time] => 2020-12-12,
[src] => ./upload/xxx.avi
)
[1] => stdclass object (
[title] : 《觉醒》,
[director] : 王家卫,
[actors] : Lebron james,
[time] : 2019-1-14,
[src] : [./upload/xxx.avi]
)
)
*/
// 这里多加一个true代表设置为数组,不然设置为一个对象
$arr = json_decode($str, true);
$arr2 = Array(
"name" => "tylor",
"age" => 32,
"gender" => true
);
// 转换为json格式的字符串
$str2 = json_encode($arr2);
echo $str2;
/* {
"name" : "tylor",
"age" : "20",
"gender" : true
}
*/
?>
要开启session的功能,才能使用session
// !!! php中默认不能使用session功能,如果需要使用则需要手动设置
session_start();
/*
1, 在服务器端动态生成一个sessionID
2, 在服务器端动态生成一个可以存放本次会话数据的文件,文件名以sess_sessionID构成
3, 通过相应头动态设置cookie, 在cookie中存放了本次会话所生成的sessionID
*/
// 创建session 使用超全局变量 $_SESSION["name"] = value;
$_SESSION["user"] = Array(
"name" => "dilireba",
"age" => 25
);
?>
C:\phpStudy\PHPTutorial\tmp\tmp
修改配置文件
// 搜索 session.auto_start 将原本的0改为1即可
session_start();
$str = $_SESSION["username"];
?>
session_start();
// 删除一个session的值
unset($_SESSION["username"]);
// 清空session所有的值
$_SESSION = [];
// 销毁session文件
session_destroy();
?>
...
// 匹配成功跳转至主页,否则回到登录页
/*
!!!!! 将登陆成功的数据,写入到cookie中
setcookie("isLogin", true);
*/
// 写入session数据
session_start();
$_SESSION["user"] = Array(
"username" => $_POST["username"],
"userpwd" => $_POST["password"],
"isLogin" => "yes"
);
header("Location:./main.php");
...
?>
session_start();
// 判断是否写入了session
if(!isset($_SESSION["user"]) || $_SESSION["user"]["isLogin"] !== "yes") {
header("Location:login.php");
}
?>
session_start();
// 删除session
unset($_SESSION["user"]);
// 回去登录页面
header("Location:login.php");
?>
区别 | cookie | session |
---|---|---|
存储位置 | 浏览器 | 服务器 |
浏览器携带的数据量 | 多 | 少(只携带session-id) |
存储的数据类型 | 只能是字符串 | 任意类型 |
安全性 | 较低 | 较高 |
默认的有效路径 | 当前路径及其子路径 | 整站有效 |
数据的传输量 | 有限制4k,不能超过20个 | 无限制 |
存储数据的仓库,按照特定的方式来存储数据
txt => json => 数据库
第一种方式: 通过命令行工具创建数据库
默认密码:root
// 数据库命令行常见操作
mysql> show databases; -- 显示全部数据库
mysql> create database <db-name>; -- 创建一个指定名称的数据库
mysql> use <db-name>; -- 使用一个数据库,相当于进入指定的数据库
mysql> show tables; -- 显示当前数据库中有哪些表
mysql> create table <table-name> (id int, name varchar(20), age int); -- 创建一个指定名称的数据表,并添加 3 个列
mysql> desc <table-name>; -- 查看指定表结构
mysql> source ./path/to/sql-file.sql -- 执行本地 SQL 文件中的 SQL 语句
mysql> drop table <table-name>; -- 删除一个指定名称的数据表
mysql> drop database <db-name>; -- 删除一个指定名称的数据库
mysql> exit|quit; -- 退出数据库终端
在 学 习 过 程 中 , 一 定 要 记 住 不 要 被 知 识 点 弄 的 眼 花 缭 乱 , 要 分 清 主 次 , 划 分 重 难 点 在学习过程中,一定要记住不要被知识点弄的眼花缭乱,要分清主次,划分重难点 在学习过程中,一定要记住不要被知识点弄的眼花缭乱,要分清主次,划分重难点
关于使用命令行创建和操作数据库,这个不必要掌握,不必要给自己增加学习难度;
使用图形化软件来操作,更加直观和清晰,而且简单容易上手;
离线激活
安装好的软件,需要注册或者购买激活码,课程提供的是有激活的软件
需要在离线的状态下,打开激活软件,选中安装好的软件,点击打开即可
*** 在打开软件进行操作的时候,一定要运行phpstudy软件,因为它内部集成了MySQL的服务
连接名称没有特殊的限制(尽量不要中文),其他的信息不用改,密码默认是root
确认新建完成
右键打开连接,或者双击连接,当前数据库变为绿色亮起
在表的位置,右键新建表
如果主键为id,在底下可以设置 自动递增
建立好表头之后,就可以开始添加具体的数据了
SQL语句是所有数据同通用的操作语言
在当前面板可以打开编辑,输入执行的语句,查询到相关数据
– 双横线表示注释
常用的关键字如下
关键字 | 解释 |
---|---|
select * | 字段列表 |
from | 表列表 |
where | 条件 |
and | 多个条件 |
查询可以返回一个结果集,是一个列表
-- 查询在这张表里面的所有id列和name列
select id,name from mytable
-- 带条件的查询
select * from mytable where id = 3
-- 查询年龄小于20岁的
select * from mytable where age < 20
-- 查询年龄小于20岁,性别为女生
-- and or not
select * from mytable where age < 20 and gender = 0
insert [into] 表名[(字段1, 字段2,…)] values(值1,值2)
-- 表名后没有指定字段,那么必须设置对应数量的值,并且主键不能重复
insert into mytable values('lili', 30, 0) -- 没有id的值,所以报错
-- 如果有标识列,一般可以给null值,系统会自动生成
insert into mytable values(null, 'lili', 30, 0)
-- 指定需要添加数据的字段
insert into mytable(name, age, gender) values('lili', 30, 0)
-- 对于值为null的值,可以不写
insert into mytable(name) values("ok")
-- 非空字段需要赋值,否则系统也不会自动为其生成默认值
insert into mytable(age,gender) values(40, 1) -- 虽然可以,但是不建议漏掉非空字段
-- 修改的语法 update 表名 set 字段1 = 值1, 字段2 = 值2 ...
update mytable set age = age + 1 -- 会把所有的都改变
-- 带条件的写法,只会改变第5条
update mytable set age = age + 10 where id = 5
-- 同样支持 or and not
-- 修改多个内容
update mytable set age = age + 1,gender = 1 where id = 5
不要轻易删除内容!!!!
-- 删除语句的语法 delete [from] 表名 where 条件
-- 删除的操作不能还原,要删除的话,就需要提前备份
delete from mytable where id = 8
-- 同时删除多个
delete from mytable where id in(4,5)
==> 查询是返回受影响的内容
==> 增加、删除和修改是返回受影响的行数
总条数 count
-- 查询可以满足条件的记录数
select count(*) from mytable
-- 选择符合条件的记录数
select count(id) from mytable
-- 如果当前空值,不会对null值进行计算
最大值、最小值 max min
得到当前的那个值
-- max 获取最大值 min 获取最小值
select max(age) from mytable
-- 如果是字符,按照字符的ascll码来排序
平均值 avg
-- 一般都是数值
select svg(age) from mytable
排序 order by
select * | 字段列表 form 表列表 where order by asc 升序 desc 降序
select * from mytable
-- 降序
select * from mytable order by id desc
-- 按照name排序 a-z
select * from mytable order by name
-- null值会排在前面
-- 实现按照性别,再按照年龄
select * from mytable order by gender,age
获取指定范围内的数据
limit 获取指定的前n条记录 只有一个参数
-- 前面3条数据
select * from mytable limit 3
-- 后面五条
-- 先做降序,然后再去筛选,并且一定要先排序,再获取,不然会报错
select * from mytable order by id desc limit 5
-- 中间范围的记录 n 偏移量从0开始, m 能够获取的记录数
select * from mytable limit 2,2
-- 第2种写法,和上面的一样
select * from mytable limit 4 offset 2
制作分页
int pageSize = 10;
int pagecount = 1;
select * from mytable pageSize 4 offset (pagecount - 1) * pageSize
在数据中,防止重复存储数据,所以会把不同的数据放在不同的地方存储
-- 返回初始的数据,没有内部关联的数据
select * from student
-- 用户需要的是最终的结果
-- 1.0 采用from where的方式
select * from student,class where student.cid = class.classid -- where后面的这个 = 表示判断
-- 简写
select studentId,studentName,age,gender,className from student,class where student.cid = class.classid
-- 2.0 join 和 inner join都是一样的 on和where的意思也是差不多的
select * from student inner join class on student.cid = class.classid
-- left join 如果对应不上的时候,自动让对应的值为空 right join 与之相反
select * from student left join class on student.cid = class.classid
// 设置主机,用户名,密码,想操作的数据库
// 这个函数会自动打开连接
// 如果连接失败,返回false 如果连接成功就返回一个连接对象
$conn = mysqli_connect("localhost", "root", "root", "mybase");
var_dump($conn); // 出来一堆东西证明连接成功
// 假如出错了,错误信息会给详细的提示
if(!$conn) {
// echo "连接失败";
// return;
die("连接失败");
// exit();
} else {
echo "连接成功";
}
echo "这是连接之后的代码,如果有错误,将不会执行到这里";
?>
解决乱码的问题
// 有效
header("Content-Type:text/html;chartset=utf-8");
// 无效
// 为了保证服务器编码,与当前php编码保持一致,可以设置服务器返回数据的编码
mysqli_set_chartset($conn, "utf8");
?>
// 新增数据 创建sql语句
$sql = "insert into mytable value(null, '张三', 30, 1)";
// 执行sql语句 mysqli_query(连接对象, sql语句)
// 有返回值
$result = mysqli_query($conn, sql);
var_dump($result); // bool(true) | bool(false)
if($result) {
echo "新增成功";
} else {
echo "新增失败
";
// 输出具体的报错信息
echo mysqli_error($conn);
}
// 获取更加详细的信息
?>
修改
// 修改操作
$sql = "update mytable set age = 20 where id = 3";
$result = mysqli_query($conn, sql);
if($result) {
echo "修改功";
} else {
echo "修改失败
";
// 输出具体的报错信息
echo mysqli_error($conn);
}
?>
删除
// 修改操作
$sql = "delete from mytable where id = 4";
$result = mysqli_query($conn, sql);
if($result) {
echo "删除成功";
} else {
echo "删除失败
";
// 输出具体的报错信息
echo mysqli_error($conn);
}
?>
// 1.0 设置响应头
header("Content-Type:text/html;chartset=utf-8");
// 2.0 创建数据库连接
$conn = mysqli_connect("localhost", "root", "root", "mybase");
// 3.0 设置编码
// mysqli_set_chartset($conn, "utf8");
mysqli_query($conn, "set name as utf-8"); // 设置编码格式为utf-8
if(!$conn) {
die("连接失败");
}
// 4.0 创建sql语句
$sql = "select * from mytable";
// 5.0 执行sql语句
$result = mysqli_query($conn, $sql);
var_dump($result); // 获取到大致信息,几行几列,但是并不是具体的数据
?>
if(!$result) {
die("查询失败");
} else if(mysqli_num_rows($result) == 0) {
die("结果集为空");
} else {
var_dump($result);
}
// 1, 如果查询失败, 会返回false
// 2,如果成功,有结果集,但是没有数据, 有结果集有数据
// !!!! 判断当前结果集中是否有数据
// mysqli_num_rows($result);
?>
获取数据的函数:
// 1.0 mysqli_fetch_array
$arr = mysqli_fetch_array($result);
print_r($arr); // 关联数组和索引数组,两份
// 数据以数组的方式返回
// 2.0 mysqli_fetch_assoc
$arr1 = mysqli_fetch_assoc($result);
print_r($arr1); // 关联数组
// 数据以数组的方式返回
// 3.0 mysqli_fetch_row
$arr2 = mysqli_fetch_row($result);
print_r($arr2); // 索引数组
// 数据以数组的方式返回
?>
// mysqli_fetch_array(结果集资源, 返回内容的形式 MYSQL_ASSOC | MYSQL_NUM | MYSQL_BOTH); 常量
// 根据传值的不同,得到不同的结果,默认是both
?>
// 上面的函数都只会读取一行数据,但是在读取完毕之后,会将指针指向下一行
// 如果需要获取多行,则需要重复调用相同的方法,如果没有数据,则返回NULL
// !!!!而数据到底有多少,则未可以,所以循环的话并不知道何时停止,while循环就比较适合
while ($arr = mysqli_fetch_array($result, MYSQL_ASSOC);) {
$res[] = $arr;
}
print_r($res);
?>
方法 | 说明 |
---|---|
mysqli_connect(“主机名称”, “用户名”, “密码”, “数据库名”) | php连接MYSQL数据库 |
mysqli_set_charset(连接对象,“utf8”); | 设置数据库和服务器编码相同 |
mysqli_query($conn, “set name as utf-8”); | 设置数据库和服务器编码的另一种方式 |
mysqli_query(连接对象,sql语句) | 执行sql语句 |
mysqli_num_rows(结果集[执行完sql语句之后的值]) | 返回结果集的条数 |
mysqli_fetch_array(结果集,MYSQL_ASSOC) | 提取查询语句之后的内容,需要循环 |
mysqli_fetch_assoc(结果集) | 提取到查询语句之后的关联数组 |
mysqli_fetch_row(结果集) | 提取到查询语句之后的索引数组 |
mysqli_error(连接对象) | 返回具体的连接错误信息 |
die(”提示错误信息“) | 终止操作,提示错误信息 |
1.创建连接–建立连接
$conn = mysqli_connect(主机或IP地址,用户名,密码,数据库名称);
如果连接成功,就返回一个连接对象(资源),如果连接失败,返回false
2.设置编码:主要是解决浏览器出现乱码的问题
1.服务器端的编码和php的编码不一致:mysqli_set_charset( c o n n , " u t f 8 " ) ∣ m y s q l i q u e r y ( conn,"utf8") | mysqli_query( conn,"utf8")∣mysqliquery(conn,“set names utf-8”)
2.php的编码和浏览器端的编码不一致:header(“Content-Type:text/html;charset=utf-8”)
3.创建sql语句
1.新增:数值如果是字符串类型,一定要使用引号包含.如果数据没有使用引号包含,有可能会有错
“insert into temp value(‘张三’)”
2.删除和修改一定需要考虑是否有条件
4.执行sql语句
1.增加删除和修改:如果成功则返回true,否则返回false
2.查询:
查询失败:false
查询成功但是没有数据行:mysqli_num_rows(资源对象–引用)
查询成功也有数据行:读取数据
3.使用mysqli_query( c o n n , conn, conn,sql)
5.接收返回值
增加删除和修改:true/false
查询有结果集同时有数据
mysqli_fetch_array(查询结果集):每次读取一行数据,生成数组,里面包含两种形式的数据(索引数组,关联数组)
mysqli_fetch_assoc:每次读取一行数据,生成数组,里面只包含关联数组
mysqli_fetch_row:每次读取一行数据,生成数组,里面只包含索引数组
循环读取:
while($row = mysqli_fetch_assoc(结果集)){
$arr[] = $row;
}
mysqli_fetch_all(结果集,MYSQLI_ASSOC)
对不同表都相同操作,但是不需要重复写相同代码,只是语句不同
header("Content-type:text/html;charset=utf-8");
// 1.0 封装增加、删除和修改的操作
function opt($sql) {
// 创建连接
$conn = mysqli_connect("localhost", "root", "root", "mytable");
// 如果连接成功返回连接对象,如果不成功,返回false
if(!$conn) {
die("数据库连接失败~");
}
// 设置编码
mysqli_set_chartset($conn, "utf8");
// 执行$sql语句,接收返回值
$res = mysqli_query($conn, $sql);
// 及时关闭连接
mysqli_close($conn);
// 返回结果
return $res;
}
// 2.0 封装查询操作
function select() {
// 创建连接
$conn = mysqli_connect("localhost", "root", "root", "mytable");
// 如果连接成功返回连接对象,如果不成功,返回false
if(!$conn) {
die("数据库连接失败~");
}
// 设置编码
mysqli_set_chartset($conn, "utf8");
// 查询语句的返回值,成功返回资源(结果集),不成功返回false
$res = mysqli_query($conn, $sql);
if(!$res) {
echo "查询失败";
} else if (mysqli_num_rows($res) == 0) {
echo "没有查找到数据~";
} else {
// 有结果集也有数据行
while($arr = mysqli_fetch_assoc($res)) {
$result = $arr;
}
// 及时关闭连接
mysqli_close($conn);
return $return;
}
// 操作完毕,关闭连接
mysqli_close($conn);
}
?>
header("Content-type:text/html;charset=utf-8");
// 载入封装的文件
include_once "./common.php";
$res = opt("insert into mytable values(null, '张三', 28, '男', 1112334)");
// 如果有限制唯一的值,注意在写入的时候会报错
if($res) {
echo "新增成功";
} else {
echo "新增失败";
}
?>
案例需求:
1,通过注册页面,上传用户信息
2,在用户列表中展示所有用户的信息
创建测试数据
1,使用写好的结构和样式
2,将html页面改造成php文件
3,通过php代码,获取数据
新建common.js文件,处理查询封装
// 封装查询操作
function getData($sql) {
// 创建数据库连接
$conn = mysqli_connect("localhost", "host", "host", "heima");
mysqli_set_chartset($conn, "utf8");
// 判断连接是否成功
if(!$conn) {
die("数据库连接失败")
}
// 执行sql语句
$res = mysqli_query($conn, $sql);
// !!!! 这里替代了原始直接在页面头部打印的方式
$returnVal = "";
if(!$res) {
$returnVal = "查询失败, 难道查询姿势不正确 ?";
} else if (mysqli_num_rows($res) == 0) {
$returnVal = "数据集是空的o";
} else {
// 获取读取的信息
while($arr = mysqli_fetch_assoc($res)) {
$result[] = $arr;
}
// 断开数据库连接
mysqli_close($conn);
// 返回最终的数据
return $result;
}
// 就算读取失败也需要关闭
mysqli_close($conn);
return $returnVal;
}
?>
// 引入封装的查询模块
include "common.php";
// 调用查询的方法
$res = getData("select id,name,photo,gender,birthday from userInfo");
// 这里$res是当前的函数的返回值,函数内部也会有一些打印值,容易误导;
?>
删除默认“死”的数据,开始php模块
// 判断是不是数组,是数组就遍历,不是数组就输出值
if(is_array($res)) {
// 遍历实现数据
} else {
// 没有tr和td,所以去外面了
// echo $res;
echo "".$res." ";
}
?>
...
// 处理if中的数据
if(is_array($res) {
foreach($res as $key => $value) {
?>
<tr>
<th scope="row"> echo $value["id"] ?> </th>
<td>
<img src= echo $value["photo"] ?> class="rounded" alt= echo $value["name"] ?> />
</td>
<td> echo $value["name"] ?></td>
<td> echo $value["gender"] ?></td>
<td> echo $value["birthday"] ?></td>
<td class="text-center">
<button class="btn btn-info btn-sm">编辑</button>
<button class="btn btn-danger btn-sm">删除</button>
</td>
</tr>
} else {
echo "".$res." ";
}
}
?>
// 1.0 获取原始的数据离1970-1-1间隔的秒数
$time1 = strtotime($value["birthday"]); // 可以获取指定日期参数距离原始1970-1-1所间隔的秒数
// 2.0 获取今天距离原始值的所间隔的秒数
$time2 = time();
// 3.0 计算两个时间相关的秒数, 在转换为年龄
$age = ceil((time2 - time1) / 60 / 60 / 24 / 365); // 向上取整
echo $age;
?>
1,在原有的html上进行修改,改成php后缀名的文件
2,在头部开始判断
function register() {
// 验证用户输入
if(!isset($_POST["name"]) || trim($_POST["name"]) == "") {
$GLOBALS["msg"] = "请输入用户名";
return;
}
if(!isset($_POST["gender"]) || $_POST["gender"] == "-1") {
$GLOBALS["msg"] = "请选择性别";
return;
}
if(!isset($_POST["birthday"]) || trim($_POST["birthday"]) == "") {
$GLOBALS["msg"] = "请选择日期";
return;
}
// 判断用户是否成功选择了文件
if(!isset($_FILES) || $_FILES["img"]["error"] != 0) {
$GLOBALS["msg"] = "文件上传失败";
return;
}
}
// 判断用户是否提交了post请求
if($_SERVER["REQUEST_METHOD"] == "POST") {
register();
}
?>
// 根据查询全局中是否设置了当前变量
if(isset($GLOBALE["msg"]) && count($GLOBALE["msg"]) != 0) {
?>
<div class="alert alert-danger" role="alert"> echo $GLOBALE["msg"] ?> </div>
}
?>
// ... 上面为非空验证
// 收集用户信息
$name = $_POST["name"];
$gender = $_POST["gender"];
$birthday = $_POST["birthday"];
// name tmp_name error
// $img = "./asset/img/".$_FILES["img"]["name"];
$img = "./asset/img/".uniqid().strrchr($_FILES["img"]["name"], ".");
// 上传图片 > 如果用户选择了图片
move_uploaded_file($_FILES["img"]["tmp_name"], $img);
// 实现用户数据的添加 : 操作数据库
?>
在common.js中封装操作
// 封装增加、删除和修改操作
function opt() {
// 创建数据库连接
$conn = mysqli_connect("localhost", "host", "host", "heima");
mysqli_set_chartset($conn, "utf8");
// 判断连接是否成功
if(!$conn) {
die("数据库连接失败")
}
// 执行sql语句 成功返回true 失败返回false
$res = mysqli_query($conn, $sql);
// 关闭连接
mysqli_close($conn);
return $res;
}
?>
引入函数,操作数据
include "common.php";
// ... 接着上面的来写
// 实现用户数据的添加 : 操作数据库
// !!!!! 一定要加引号
$res = opt("insert into userInfo values(null,'$name','$img','$gender','$birthday')");
// 跳转到用户列表页
header("Location:static.php");
?>
将默认的button按钮改造为a标签,并且加入href的链接
新建del.php处理跳转的操作
/*
*/
<a href="edit.php?id=$value["id"] ?>" class="btn btn-info btn-sm">编辑</a>
<a href="del.php?id=$value["id"] ?>" class="btn btn-danger btn-sm">删除</a>
?>
include "common.php";
// 判断用户是否传入了id
if(isset($_GET["id"])) {
// 获取参数
$id = $_GET["id"];
// 生成sql语句
$sql = "delete from userInfo where id = '$id'";
// 调用函数执行sql语句
$res = opt($sql);
// 刷新页面
if($res) {
header("Location:./static.php");
}
}
?>
复制注册页面结构所有信息,存储为php文件
将标题改为编辑用户
include "common.php";
// 1.0 显示默认数据
// 判断是否为get请求,是否获取到了id
if($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET["id"])) {
// 根据id号进行查询数据
$id = $_GET["id"];
// 创建sql语句
$sql = "select id,name,photo,gender,birthday from userInfo where id = '$id'";
// 因为传递了id条件,所以数组只会存储一条记录
$res = getData($sql)
$value = $res[0];
} else if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 2.0 实现编辑操作
// 调用函数方法
editUser()
}
?>
根据获取到数据,注入到页面的表单中
<form action="$_SERVER['PHP_SELF'] ?>" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" name="name" value="$value['name'] ?>">
</div>
<div class="form-group">
<label for="gender">性别</label>
<select class="form-control" id="gender" name="gender">
<option value="-1">请选择性别</option>
<option value="男" echo $value['gender'] == "男" ? "selected" : ""; ?>>男</option>
<option value="女" echo $value['gender'] == "女" ? "selected" : ""; ?>>女</option>
</select>
</div>
<div class="form-group">
<label for="birthday">生日</label>
<!-- date:年月日 -->
<input type="date" class="form-control" id="birthday" name="birthday" value= echo $value['birthday'] ?>>
</div>
<div class="form-group">
<label for="img">头像</label>
<input type="file" class="form-control" id="img" name="img">
</div>
<button class="btn btn-primary">保存</button>
</form>
** 表单中,如果type类型和数据库里面的数据类型不一样,则不显示
在form表单中,增加一个隐藏的input作为接收参数使用
<input type="hidden" name="id" value = "$value["id"] ?>">
include './common.php';
// 创建函数实现编辑操作
function editUser(){
// 验证用户数据
if(!isset($_POST["name"]) || trim($_POST["name"]) === ''){
$GLOBALS["error"] = '请输入用户名';
return;
}
if(!isset($_POST["gender"]) || $_POST["gender"] === '-1'){
$GLOBALS["error"] = '请选择性别';
return;
}
// 收集用户数据
$id = $_POST["id"];
$name = $_POST["name"];
$gender = $_POST["gender"];
$birthday = $_POST["birthday"];
if(!empty($_FILES["img"]["name"]) && $_FILES["img"]["error"] == 0){
// 实现文件上传操作
$fileName = "./assets/img/".uniqid().strrchr($_FILES["img"]["name"],".");
move_uploaded_file($_FILES["img"]["tmp_name"],$fileName);
// 重新为$photo赋值
$photo = $fileName;
// 创建sql语句,执行编辑操作
$sql = "update userInfo set name = '$name',gender = '$gender',birthday = '$birthday',photo = '$photo' where id = '$id'";
}else{
$sql = "update userInfo set name = '$name',gender = '$gender',birthday = '$birthday' where id = '$id'";
}
$res = opt($sql);
if($res){
// 实现页面的跳转
header("Location:./static.php");
}
}
?>