了 解 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 // 在php中,表述输出当前的时间 echo date('Y-m-d'); ?> 1, echo 输出字符串,多个字符串用逗号
<?php // 不识别多个空格 echo "123", "adfdf"; ?> 2, print( ) 输出字符串, 只能输出一个值
<?php print("abc") ?> 3,print_r( ) 输出复杂的数据类型
<?php print_r([1, 2, 3]) // 输出: Array([0] => 1 [1] => 2 [2] => 3) echo [1, 2, 3] // 输出:Array ?> 4,var_dump( ) 可以输出复杂类型,输出复杂类型的key和value
<?php var_dump(['ab', 'fbb', 'exo']) // 输出:array(3) { [0] => string(2)'ab' [1] => string(3)'fbb' [2] => string(3)'exo' } ?> 1, php的代码只要不在那一堆尖括号里面,则不会执行,会原样输出
echo "abc" // 原样输出 <?php //... ?> 2,php语法中也是存在多分支语句,也就是if语句
<?php if(true) { echo '结果为真' } ?> <?php if (true) { ?> // 这句话是在php语法结构以外 <h2>结果为真</h2> <?php } ?> ** 所有的代码必须都得在php的代码以内
<?php // 变量不需要关键字声明,不过都得加上$开头,区分大小写,其他跟js一样 $age = 20; echo $age; $name = 'jack'; /* 如果不赋值,默认是null */ ?> isset( )
// 如果返回结果为true那么返回 1 如果返回结果为fall,那么返回null <?php $name = 'abc'; echo isset($age); // 空白 echo '</br>'; echo 123; var_dump(isset($age)); // boolean(false) ?> empty( ) 如果为空值就返回true
<?php $name = 'abc'; $num = 0; echo empty($age); echo empty($num); var_dump(empty($num)); // boolean(true) ?> unset( ) 删除变量
<?php $name = 'abc'; $age = 20; echo $name; echo '</hr>'; unset($name); // unset($name, $age) echo $name; ?> js中的数据类型主要有以下几种
数据类型解释string字符串integer整型 - 只能是整数float浮点型 - 小数boolean布尔型 - true或者falsearray数组object对象NULL空 PHP可以按照以下方式分成三个种类:
基本数据类型复合数据类型特殊类型string 字符串array 数组NULL 空integer 整型 - 只能是整数object 对象资源float 浮点型 - 小数boolean 布尔型 - true或者false
检测数据类型的方法:
方法名称功能is_string( )判断当前变量是否为字符串类型is_bool( )判断当前变量是否是布尔类型is_int( )判断是否是整型is_float( )判断是否是浮点型is_array( )判断是否为数组类型is_object( )判断当前变量是否是对象类型
<?php $name = 'delireba'; $age = 20; echo is_string($name); // 1 var_dump(is_string($name)); // boolean(true) var_dump(is_bool($age)); // ?> 在php中,字符串的使用是有区别的 在php中,字符串的拼接使用小数点,而不是使用加号
<?php $name = 'fbb'; echo $name; // fbb /* 在php中,字符串的拼接使用小数点,而不是使用加号 */ echo '她的名字叫'.$name ?> 单引号的特点
<?php /* 在单引号中有变量的话,单引号无法解析 */ $name = 'yiyang'; echo '我的名字叫$name'; // 我的名字叫$name // 而且出现单引号嵌套或者斜杠 需要通过斜杠来转义 echo '我的\\名字\'叫$name'; // 我的\名字'叫$name ?> 双引号的特点
<?php /* 在双引号中有变量的话,双引号就会解析 */ $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(添加数组的成员, 成员类型不限)
<?php $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) <?php $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 . "</br>"; } /* => 输出 name:yiyang age:20 gender:1 */ // 简洁语法 foreach($arr as $value) { echo $value . "</br>"; } ?>
** 所有的数组本质上都是关联数组, foreach方法也可以操作索引数组;
** 如果通过空的中括号赋值,会自动追加和排序,还会变成混合数组
count( ) 计算数组的长度length
unset( ) 使用数组删除某一项会有一点点小问题
<?php $arr = [1, 2, 3, 4, 5]; print_r($arr); unset($arr[2]) echo '<hr/>'; print_r($arr); /* 之前: Array([0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5) 现在: Array([0] => 1 [1] => 2 [3] => 4 [4] => 5) */ // 索引和值都没有,变成了稀疏的了 ?> 主要分为两种,自动转换和强制类型转换,也就是显式转换和隐式转换,自动转换用的多
bool( ) string( ) object( )
<?php $str = '123'; var_dump($str); // string(3) '123' var_dump((int)$str); // int(123) echo '<br/>'; // 转换成数组 var_dump((array)$str); // Array {[0] => string(3) '123'} $abc = 'jackey'; $num = (int)$abc; var_dump($num); // int(0) ?>+号只能是运算符,系统默认会隐式转换成数值,如果转换不了,就会给一个默认值
默认值类型
数据类型默认值int0objectnullboolfalsefloat0.0在php中,拼接的运算符,是小数点.
运算符类型
算术运算符赋值运算符逻辑运算符比较运算符+ 加 - 减 * 乘 / 除= 一般赋值!取反> 大于 < 小于% 求余,相除完剩余的结果+= 在本身追加&& 与,严格要求>= 大于等于 <=小于等于++ 自加单独没区别-= 在本身扣除|| 或,满足一项== 是否相等 === 是否全等– 同上*= /= 同上逻辑!= 不相等 !== 不全等三元运算符 表达式会返回true或者false ? 如果为true返回值1 : 如果为false返回值2
顺序结构 => 流程控制 => 循环
习惯使然,没有什么强制要求;
预设常量(魔术常量)
在不同的使用场景下,代表不同的值
常量名称作用_LINE_可以获取当前的代码行_FILE_可以获取当前文件的路径 目录+文件名_DIR_可以获取当前文件的目录_FUNCTION_可以获取当前魔术常量所在的函数 09 10 <?php 11 echo __LINE__; // 11 返回当前的行号 12 ?> 13 说明: 在一个文件中引入另外一个文件的方法
html,css都有类似的方法,但是javascript不行,所以才有了后期的模块化
01-constant.php 用来描述一些固定的信息
<?php define("__SCHOOL_NAME", "传智播客"); define("__ADDRESS__", "首都北京"); echo "下面是被入的代码块"; ?> 02-require.php 用来载入上面的文件
<?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; // 传智播客 ?> requirerequire_onceincludeinclude_once载入文件不存在是否影响后续代码执行会会不会不会多次调用是否重复执行被载入的文件会不会会不会总结:
include一般用于载入公共文件,这个文件的存在与否不能影响后续代码执行require用于载入不可或缺的文件至于是否采用一次载入这种方式取决于被载入的文件 这里的api指的就是一些方法,或者内置函数
strlen( )
<?php $str = "hello world"; // 获取字符串的长度 // 无法正确处理中文字符(宽字符集:php默认不支持的字符-中文、韩文、日文) echo strlen($str); // 11 加两个中文就变17 一个中文3个字节 ?> <?php // 获取函数内部默认的编码 echo mb_internal_encoding(); // UTF-8 ?>mb_strlen( )
<?php $str = "hello world你好"; // 没有变化就使用默认编码 // 默认不能使用,如果想使用,就需要添加一个引用 echo mb_strlen($str); // 13 ?>解开注释掉的那个引用
使用搜索查找到当前那个位置, 选择记事本打开,按住ctrl+f查找
去掉前面的分号,!!!!!一定要记得手动重启一下服务器;
备注:只有php5.6版本以上才支持,切换后点击应用
修改配置文件
搜索timezone
点击查找下一个,找到属于这个开头的
!!!!手动重启服务器
strtotime( )
<?php echo strtotime("1970-1-2 00:00:00"); // 57600 ?>静态网页生成:
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>如果使用javascript可以依照如下代码结构
<script> var str = "img/pineapple1.jpg|菠萝"; console.log(str.split("|")); // ["img/pineapple1.jpg", "菠萝"] </script>新建一个 data.txt 文件存入数据
img/pineapple1.jpg|菠萝在php文件中引入数据
<?php // !!!! 在这里引入了数据文件 $str = file_get_contents("data.txt"); $value = explode("|", $str); ?> <li> <img src="<?php echo $value['src'] ?>" alt="" /> <a href="#"><?php echo $value['name'] ?></a> </li>在文件结构首页引入php功能的文件
<?php include 'getList.php'; ?>引入最终的完整的txt文档,改变内层拆分的索引
###1.php标记
<?php 1.写在这个结构内的代码才会以php语法解析 2.写在这个结构外的代码会原样返回 ?>#2、输出内容的方式
echo:输出多个字符串 print:输出一个字符串值 print_r:可以输出复杂数据类型,如数组,以键值对的形式输出 var_dump:可以输出复杂数据类型,如数组,以键值对的形式输出,还可以输出数据的长度###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<count(数组);$i++){} foreach(需要遍历的数组对象 as $key => $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.在<?php 在这个结构内部只能写符合php语法的代码 ?> 2.在<?php ?>结构的代码会原样输出 3.混编实现方式 1.<?php echo '<p></p>' ?> 2. <?php if(){ ?> <p></p> <php }?> 浏览器向线上服务器请求获取资源的一种方式。
1.1.1 正常请求资源的方式
在地址栏通过url发起请求标签中src和href属性表单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文件
<?php // $_GET 可以接收客户端以get方式传递的数据 // echo $_GET; 关联数组 print_r($_GET); // Array([userName] => jack [userPwd] => 123) echo '我的名称是'.$_GET['userName123'].', 我的密码是'.$_GET['userPwd']; ?> <!DOCTYPE html> <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>Document</title> </head> <body> <!-- action: 设置提交数据的处理页面,是一个后台文件的地址 method:如果没有设置,默认请求方式为 get get 一般用来获取数据, 参数会在url中拼接 post 一般用来发送数据到服务器 --> <form action="form-get.php" method="get"> <!-- !!! 如果提交表单元素,一定要保证元素有name属性 提交的时候,在浏览器地址栏就会自动生成key值 --> 用户名: <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
<?php ... foreach($result as $value) { ?> <li> <img src="<?php echo $value[1] ?>" alt="" /> <a href="./detail.php?id=<?php echo $value[0] ?>"><?php echo $value[2] ?></a> </li> <?php } ?> 在页面最顶部使用$_GET接收参数
<?php $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="<?php echo $data[1] ?>" alt="" /> <p> <?php echo $data[2] ?></p> </li> 需要将form表单中的属性更改,将method属性设置为post,将action属性改变地址
当前的文件名称为 form-post.php
<form action="form-post.php" method="post"> <!-- !!! post请求不会在地址栏 --> 用户名: <input type="text"> <br> 密码: <input type="password"> <br> <input type="submit"> <br> </form> 在当前文件的最顶部用 $_POST来接收发送的值
<?php // !!! 判断当前用户是否发送了请求, 是否是以post方式 // print_r($_SERVER); 很大一串关联数组, REQUEST_METHOD if($_SERVER['REQUEST_METHOD'] === 'POST') { echo '我的名称是'.$_POST['userName123'].', 我的密码是'.$_POST['userPwd']; } ?>_$REQUEST 这个能接收到get或者post两者任何一种方式提交的数据
** 效率低下,受配置文件的影响,不怎么推荐使用
getpost后退按钮/刷新无害数据会被重新提交(浏览器应该告知用户数据会被重新提交)书签可收藏为标签不可收藏为书签缓存能被缓存不能缓存编码类型application/x-www-form-urlencodedapplication/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码历史参数保留在浏览器历史中参数不会保存在浏览器历史中对数据长度的限制是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)无限制对数据类型的限制只允许 ASCII 字符没有限制。也允许二进制数据安全性与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分,在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中可见性数据在 URL 中对所有人都是可见的数据不会显示在 URL 中
<!DOCTYPE html> <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>Document</title> </head> <body> <!-- action: 提交地址为了不写固定了,可以使用 $_SERVER["PHP_SELF"] method:get / post --> <form action="<?php echo $_SERVER["PHP_SELF"] ?>" method="get"> 用户名: <input type="text" name="userName"> <br> 密码: <input type="password" name="userPwd"> <br> 性别:<input type="radio" name="gender" value="1"> 男 <input type="radio" name="gender" value="0"> 女 <br> 爱好:<input type="checkbox" name="hobby[]" value="code"> 写代码 <input type="checkbox" name="hobby[]" value="reading"> 看书 <br> <select name="subject" id=""> <option value="1">前端</option> <option value="2">JAVA</option> <option value="3">IOS</option> <!-- 如果没有设置value属性, 会默认收集当前被选中的option的内容, 如果设置了value则传入value值,常见的开发中肯定要加入value的值 --> </select> <input type="submit"> <br> </form> </body> </html> 在文件的顶部书写php代码
<?php print_r($_GET); // 不管在怎么选择, 但是gender始终是on // Array([userName] => jack [userPwd] => 123 [gender] => on) /* ==> 单选框 系统会自动的收集当前表单元素的value值 解决办法: 给单选按钮添加value值,区分一下 */ /* ==> 复选框 如果复选框的名称一样,那么就会默认传递最后一个选项的值 如果需要传入所有选中的复选框的数据,可以在name属性值后面添加[] 添加了[], 在收集数据的时候,就会把他们放进一个数组内 eg: 爱好:<input type="checkbox" name="hobby[]" value="code"> 写代码 <input type="checkbox" name="hobby[]" value="reading"> 看书 <br> */ ?> 文件上传遵循的流程:
选取文件提交 ==> 存入服务器暂存区 ==> 有后续操作后存入到服务器
由于发送的是post请求,结果文件一打开的时候就开始了一些操作,发现报错了
所以,在打开文件的时候,还得需要一些判断
<?php // 判断当前的数组是否为空,为空则不进入 if(!empty($_FILES)) { move_uploaded_file($_FILES["myFile"]["tmp_name"], "./upload/temp.png") } ?> // !!!通过表单元素的属性,限制文件上传的格式 // 1, 在表单元素中可以限制 <input type="file" accept=".jpg,.png" /> // 2, 在后端进行判断 <?php 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 "您选择的不是一张图片"; } } ?> 文件名称不固定,设置合理的文件名称
<?php // 获取当前文件的名称 $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
在文件中搜索
找到位置后,该变原有的大小
同时上传多个文件
<!-- 在选择的表单元素中加入multiple, 则可以选中多个文件 --> <input type="file" name="myfile" multiple>_1.0 如果需要后端服务器的 $FILES 接收多个文件,则需要在name属性值后面加上[ ]
<input type="file" name="myfile[]" multiple>2.0 实现完成效果
<?php /* 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); } } ?>综合性案例
直接使用写好的结构代码进行修改
将静态的文件修改为动态的文件
由于当前的return会结束整个php文件,修改后变成如下情况
<?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)将字符串以某个符号进行分割,返回一个数组 <?php // 使用函数声明 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(); } ?> 实现图片的上传操作
<?php // 判断图片上传操作是否成功 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次握手?
这个问题的本质是, 通信不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值
已失效的连接请求报文段的产生在这样一种情况下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接 在结束协议的连接之后,客户端向服务器正式发起请求
发起请求的时候,需要具体介绍当前的请求情况,方便服务器做出快速响应
请求报文包含 请求行–请求头–请求体
请求方式 + 空格 + 请求路径 + 空格 + HTTP协议版本
=> GET /demo.php HTTP/1.1
客户端需要向服务端发送的内容
get请求,会把基本的参数拼接到url的后面,所以基本使用不上请求体post请求使用请求体会比较频繁 get请求没有请求体,因为都在url的问号后面
如果上传文件的话
响应体一般来说是HTML,也可以是css或者javascript
注意:返回什么类型文件,就修改响应头里的响应类型
虽然要请求的是css文件,但是link的是php文件
由于php是后台文件,最终是在php中返回内容给浏览器,并且可以设置当前的文件类型
<link rel="stylesheet" href="css.php" /> 在css.php中书写的代码
<?php // 设置响应头的类型 header("Content-Type:text/css;charset=utf-8;"); echo "body{background:red;}"; ?> 页面跳转
<a href="data.php">点击重定向</a> 在data.php中完成跳转
<?php // 立马做出跳转 // header("Location:01-getsmt.php"); // 在指定的时间之后跳转 header("refresh:3;url=01-getsmt.php"); ?>
客户端打开与服务器的连接发出请求到服务器响应客户端请求的全过程称之为会话
HTTP协议,本来是进行共享多个计算机之间的文件而产生的文件传输协议
而请求的时候,服务器没有记录当前的信息
就比如,去火车站取票,刷身份证拿到票之后,整个会话结束,不会有任何记录
==============
动态网站的出现,表单提交,购物车的DOM操作,付款的跳转…
有了交互的需要,需要携带一些数据在不同页面之间跳转,无凭无据的,可如何是好
cookie是一个文件,用来存储当前的一些信息和服务器保持交流
在前端介绍的sessionStorage和localStorage也是类似的功能
内容cookielocalStoragesessionStorage生命周期一般由服务器生成,可设置失效的时间,如果在浏览器端生成cookie,默认关闭浏览器后失效除非被删除,否则永久保存仅在当前会话下有效,关闭页面或者浏览器后被删除数据大小4k20M5M与服务器端通信携带在http请求头中,若保存cookie过多数据会带来性能问题仅在客户端即浏览器中保存,不参与和服务器的通信仅在客户端即浏览器中保存,不参与和服务器的通信易用性需要程序员自己封装原生接口可以接受,亦可以再次封装来对obj和Arr有更好的支持原生接口可以接受,亦可以再次封装来对obj和Arr有更好的支持 chrome: 设置 => 更多设置 => 内容设置 => cookie
可以看到明文存储的cookie设置的值;
cookie的有效期
<?php // 时间是秒, 时间参照php的默认起始时间(1970-1-1) // setcookie("username", "tylor", 100); setcookie("username", "tylor", time() + 10); // 设置永久的时间 setcookie("username", "tylor", PHP_INT_MAX); ?> cookie的有效目录
<?php // 在不同的文件夹输出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 ?> 使用写好的表单文件, 在头部判断是否为post提交
<?php 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(); } ?> <?php // 判断当前有没有定义全局成员 if(isset($GLOBALS["error"])) { ?> <div class="alert alert-danger" role="alert"><?php echo $GLOBALS["error"] ?></div> <?php } ?> 在跳转的首页去判断用户是否之前登录过
<?php // 约定好判断的名字是什么 if($_COOKIE["isLogin"] != true) { header("Location:login.php"); } ?> 在点击退出登录的页面中,设置跳转到logout.php文件,在此文件中处理删除
<?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" } ] 要开启session的功能,才能使用session
<?php // !!! 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即可 存储数据的仓库,按照特定的方式来存储数据
txt => json => 数据库
前两者存储量小,不利维护,不利管理,不利更新数据库主要逻辑 (增删查改)CRUD 第一种方式: 通过命令行工具创建数据库
默认密码: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) -- 虽然可以,但是不建议漏掉非空字段 不要轻易删除内容!!!!
-- 删除语句的语法 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解决乱码的问题
<?php // 有效 header("Content-Type:text/html;chartset=utf-8"); // 无效 // 为了保证服务器编码,与当前php编码保持一致,可以设置服务器返回数据的编码 mysqli_set_chartset($conn, "utf8"); ?>修改
<?php // 修改操作 $sql = "update mytable set age = 20 where id = 3"; $result = mysqli_query($conn, sql); if($result) { echo "修改功"; } else { echo "修改失败<br>"; // 输出具体的报错信息 echo mysqli_error($conn); } ?>删除
<?php // 修改操作 $sql = "delete from mytable where id = 4"; $result = mysqli_query($conn, sql); if($result) { echo "删除成功"; } else { echo "删除失败<br>"; // 输出具体的报错信息 echo mysqli_error($conn); } ?> 获取数据的函数:
<?php // 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); // 索引数组 // 数据以数组的方式返回 ?> <?php // mysqli_fetch_array(结果集资源, 返回内容的形式 MYSQL_ASSOC | MYSQL_NUM | MYSQL_BOTH); 常量 // 根据传值的不同,得到不同的结果,默认是both ?>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)
对不同表都相同操作,但是不需要重复写相同代码,只是语句不同
案例需求:
1,通过注册页面,上传用户信息
2,在用户列表中展示所有用户的信息
创建测试数据
1,使用写好的结构和样式
2,将html页面改造成php文件
3,通过php代码,获取数据
新建common.js文件,处理查询封装
<?php // 封装查询操作 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; } ?> 删除默认“死”的数据,开始php模块
<?php // 判断是不是数组,是数组就遍历,不是数组就输出值 if(is_array($res)) { // 遍历实现数据 } else { // 没有tr和td,所以去外面了 // echo $res; echo "<tr><td colspan='6'>".$res."</td></tr>"; } ?> 1,在原有的html上进行修改,改成php后缀名的文件
2,在头部开始判断
在common.js中封装操作
<?php // 封装增加、删除和修改操作 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; } ?>引入函数,操作数据
<?php include "common.php"; // ... 接着上面的来写 // 实现用户数据的添加 : 操作数据库 // !!!!! 一定要加引号 $res = opt("insert into userInfo values(null,'$name','$img','$gender','$birthday')"); // 跳转到用户列表页 header("Location:static.php"); ?> 将默认的button按钮改造为a标签,并且加入href的链接
新建del.php处理跳转的操作
<?php /* <button class="btn btn-info btn-sm">编辑</button> <button class="btn btn-danger btn-sm">删除</button> */ <a href="edit.php?id=<?php echo $value["id"] ?>" class="btn btn-info btn-sm">编辑</a> <a href="del.php?id=<?php echo $value["id"] ?>" class="btn btn-danger btn-sm">删除</a> ?> 复制注册页面结构所有信息,存储为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="<?php echo $_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="<?php echo $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="男" <?php echo $value['gender'] == "男" ? "selected" : ""; ?>>男</option> <option value="女" <?php 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=<?php 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 = "<?php echo $value["id"] ?>"> <?php 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"); } } ?>