🌈学习PHP笔记(二)
包含文件的方式(可多次包含)
require
<?php
require '文件目录';
?>
include
<?php
include '文件目录';
?>
包含文件的方式(一次包含)
require_once:
include_once:
区别:
1、require:遇到错误抛出error类别的错误,停止执行
2、include:遇到错误抛出warning类型的错误,继续执行
3、require_once:、include_once:只能包含一次
4、HTML类型的包含页面中存在PHP代码,如果包含到PHP中是可以被执行的
5、包含文件相当于把包含文件中的代码拷贝到主文件中执行,魔术常量除外,魔术常量获取的是所在文件的信息。
6、被包含的文件在主文件被编译时不执行、运行时加载到内存、独立编译包含文件
包含文件的路径
./ 当前目录
../ 上一级目录
这个是没有指定目录直接写文件名,PHP的寻找机制,这些显示寻找顺序从左往右的目录依次查找。
使用来进行包含文件的目录,可以设置多个,路径之间用分豪隔开。
<?php
set_include_path('目录1;目录2;目录3');
?>
关于正反斜杠
正斜(/):web中目录分隔用正斜:https://erhe.group/
反斜(\):物理地址的分隔用反斜,( windows中物理地址正斜和反斜都可以):c:\web\test\
❌PHP错误处理
错误的级别
1、notice:提示
2、warning:警告
3、error:致命错误
notice和warning报错后继续执行,error报错后停止执行
错误的提示方法
方法一:直接显示在浏览器上
方法二:记录在日志中
错误处理的有关配置
在PHP的配置文件中有一个php.ini配置文件
1、error_reporting = E_ALL // 报告所有的错误
2、display_errors = On // 将错误显示在浏览器上
3、log_errors = On // 将错误记录在日志中
4、error_log = '文件路径' // 错误日志保存的位置
在项目开发中有两个模式:
开发模式:错误显示在浏览器上,不要记录在日志中
运行模式:错误不显示在浏览器上,记录是日志中
<?php
$debug=false; // 开发模式
ini_set('error_reporting',E_ALL); // 所有的错误有报告
if($debug){
ini_set('display_errors','on'); // 错误显示是在浏览器上面
ini_set('log_errors','off'); // 错误不显示在日志中
}else{
ini_set('log_errors','off');
ini_set('log_errors','on');
ini_set('error_log','文件路径'); // 错误日志保存的位置
}
?>
PS:ini_set()
是用来设置PHP的配置参数。
自定义错误处理
通过trigger_error('')
产生一个用户级别的error/warning/notice信息
<?php
$age=100;
if($age>80){
trigger_error('年龄不能超过80岁'); //默认触发了notice级别的错误
trigger_error('年龄不能超过80岁',E_USER_NOTICE); // 触发了notice级别的错误
trigger_error('年龄不能超过80岁',E_USER_WARNING); // 触发了warning级别的错误
trigger_error('年龄不能超过80岁',E_USER_ERROR); // 触发了error级别的错误
}
?>
⭕注意:用户级别的错误的常量名中一定要带有USER
自定义错误处理函数
<?php
function error(){
echo '这是自定义错误处理';
}
set_error_handler('error'); // 注册处理函数,只要有错误就会自动的调用处理函数
?>
还可以带上参数
@param $errno int 错误类别
@param $errstr string 错误信息
@param $errfile string 文件地址
@param $errline int 错误行号
<?php
function error($errno,$errstr,$errfile,$errline){
switch($errno){
case E_NOTICE:
case E_USER_NOTICE:
echo '记录在日志中,管理员上班后处理<br>';
break;
case E_WARNING:
case E_USER_WARNING:
echo '给管理员发邮件<br>';
break;
case E_ERROR:
case E_USER_ERROR:
echo '给管理员打电话<br>';
break;
}
echo "错误信息:{$errstr}<br>";
echo "错误信息:{$errfile}<br>";
echo "错误信息:{$errline}<br>";
}
set_error_handler('error'); // 注册处理函数
?>
📂PHP文件编程
文件夹操作
创建文件夹
格式:mkdir('目录/文件夹名,权限,是否递归创建')
普通创建文件夹
<?php
mkdir('目录/文件夹名'); // 目录必须存在
?>
递归创建文件夹
<?php
mkdir('目录/目录/目录/文件夹名',0777,true);
?>
删除文件夹
<?php
rmdir('目录/文件夹名'); // 删除的目录一定为空才能删除
?>
重命名文件夹
<?php
rename('目录/旧文件夹名','目录/新文件夹名');
?>
判断是否是文件夹
<?php
echo is_dir('目录/文件夹名')?'是文件夹':'不是文件夹';
?>
打开和读取遍历文件夹
<?php
$erhe=opendir('目录/文件夹名'); // 打开文件夹
var_dump($erhe); // 文件夹在PHP中是资源型
echo '<hr>';
echo readdir($erhe),'<br>'; // 读取文件夹,每次只读1个
echo readdir($erhe),'<br>'; // 再次读取文件夹,每次只读1个
echo readdir($erhe),'<br>'; // 再次读取文件夹,每次只读1个
echo '<hr>';
// 若要一次性遍历完文件夹就使用下面的代码
while($f=readdir($erhe)){
echo $f,'<br>';
}
echo '<hr>';
// 若中文有乱码加上编码转换
while($f=readdir($erhe)){
echo iconv('gbk','utf-8',$f),'<br>';
}
echo '<hr>';
// 去掉显示的.与..
while($f=readdir($erhe)){
if($f=='.' || $f=='..')
continue;
echo iconv('gbk','utf-8',$f),'<br>';
}
echo '<hr>';
?>
关闭文件夹
closedir($xxx);
📝PHP文件操作
将字符串写入文件
<?php
$erhe="床前明月光,\r\n疑是地上霜。";
file_put_contents('目录/文件名',$erhe); // 若文件没有可以自动创建文件,
?>
⭕注意:写入文件的时候是把文件清空重写,在文本中换行是\r\n
,带有转义符一定要用双引号!
\r:回车 光标移动到当前行的最前面
\n:换行 将光标下移动一行
文件的读取
将文件读入一个字符串
<?php
echo file_get_contents('目录/文件名');
echo '<hr>';
readfile('目录/文件名');
?>
打开文件
打开文件并操作
<?php
fopen('目录/文件名','模式');
// 模式:
// r:读 read
// w:写 write
// a:追加 append
?>
写入
<?php
$erhe=fopen('目录/文件名','w'); // 打开文件
fputs($erhe,'写入的内容'."\r\n"); // 写入内容,只写一行
fclose($erhe); // 关闭文件
?>
读取
<?php
$erhe=fopen('目录/文件名','r'); // 打开文件
while($f=fgetc($erhe)){ // 读取文件
echo $f,'<br>';
}
fclose($erhe); // 关闭文件
?>
⭕注意:如果只用fgetc($xxx)
就只写一行
追加
<?php
$erhe=fopen('目录/文件名','a'); // 打开文件
fputs($erhe,'追加的内容'); // 追加文件
fclose($erhe); // 关闭文件
?>
⭕注意:打开文件进行操作的时候,如果文件不存在将会报错
判断是否是文件
<?php
echo is_file('目录/文件名')?'是文件':'不是文件';
?>
判断文件或者是文件夹是否存在
<?php
echo file_exists('目录/文件名')?'文件存在':'文件不存在';
?>
删除文件
<?php
$erhe='./text.txt';
if(file_exists($erhe)){
if(is_dir($erhe))
rmdir($erhe);
elseif(is_file($erhe))
unlink($erhe);
}else {
echo '文件或者是文件夹不存在!';
}
?>
二进制读取
<?php
$erhe='目录/文件名';
$fp=fopen($erhe,'r'); // 读取文件
header('content-typpe:文件类别/文件格式'); // 告诉浏览器以那种形式显示
echo fread($fp,fileesize($erhe)); // 二级制读取
// fileesize()用来获取文件大小
?>
<?php
header('content-typpe:文件类型/文件后缀名'); // 告诉浏览器以那种形式显示
echo file_get_contents('目录/文件名') // 二级制读取
?>
⭕注意:文本流有明确的结束符,二进制没有明确的结束符,就用过文件大小来判断文件是否读取完毕
echo file_get_contents()
即可用来字符流的读取,也能进行二进制的读取。
✍️表单提交数据的两种方式
两种方式
1、get
2、post
两者区别
原理
get:数据参数一个个的提交
post:数据参数变成整体一次性提交
外观
get:提交数据的时候可以在地址栏上看到提交的参数
post:提交数据的时候地址栏上看不到提交的参数
安全性
get:不安全
post:安全
提交数据的大小
get:提交一般不超过255个字节
post:提交的大小取决于服务器
PS:在php.ini
中可以配置post提交的大小
post_max_size = 大小
灵活性
get:很灵活,只要有页面的跳转就可以传递参数
post:不灵活,post提交需要有表单的参与
html跳转
<a href="index.php?name=tom&age=20">这里是跳转</a>
JS跳转
<script>
location.href='index.php?name=tom&age=20';
location.assign='index.php?name=tom&age=20';
location.replace='index.php?name=tom&age=20';
</script>
PHP跳转
<?php
header('location:index.php?name=tom&age=20');
?>
📥服务器接受数据的三种方式
通过名字获取相应的值
$_POST:数组类型,保存的POST提交的值
$_GET:数组类型,保存的GET提交的值
$_REQUEST:数组类型,保存的GET和POST提交的值
不推荐使用$_REQUEST
,占用资源较多
关于$_REQUEST
在一个请求中,既有get又有post , get和post传递的数据是一样的,这时候通过$_REQUET
获取的数据就要根据配置文件来选择处理保存以及提交数据。
request_order = "GP" # 先获取GET,再获取POST值,后面获取的会将前面获取的值覆盖掉
PS:
1、在开发的时候,如果明确是post提交就使用$_POST
获取,如果明确get提交就用$_GET
获取
2、request获取效率低,尽可能不要使用,除非提交的类型不确定的情况下才使用。
🤝参数传递
复选框值的传递
复选框命名要注意带’[]'。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>某人的几大爱好</title>
</head>
<body>
<?php
if(isset($_POST['button'])){
print_r($_POST['hobby']);
}
?>
<from method="post" action="">
某人的几大爱好:
<input type="checkbox" name="hobby[]" value="爬山">爬山
<input type="checkbox" name="hobby[]" value="爬山">抽烟
<input type="checkbox" name="hobby[]" value="爬山">喝酒
<input type="checkbox" name="hobby[]" value="爬山">网吧
<input type="checkbox" name="hobby[]" value="爬山">打牌
<input type="submit" name="button" value="提交">
</from>
</body>
</html>
PS:
1、表单提交到本页面需要判断一下是否有post提交。
2、数组的提交表单元素的名字必须带有’[]'。
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>某人的几大爱好</title>
</head>
<body>
<?php
if(isset($_POST['button'])){
echo '姓名:'.$_POST['username'].'<br>';
echo '密码:'.$_POST['pwd'].'<br>';
echo '性别:'.$_POST['sex'].'<br>';
echo '爱好:',isset($_POST['hobby'])?implode(',',$_POST['hobby']):'没有爱好','<br>';
echo '籍贯:'.$_POST['jiguan'],'<br>';
echo '留言:'.$_POST['words'],'<br>';
}
?>
<from method="post" action="">
姓名:<input type="text" name="username"><br />
密码:<input type="passwd" name="pwd"><br />
性别:<input type="radio" name="sex" value='1' checked>男
<input type="radio" name="sex" value='0'>女<br />
爱好:
<input type="checkbox" name="hobby[]" value="爬山">爬山
<input type="checkbox" name="hobby[]" value="爬山">抽烟
<input type="checkbox" name="hobby[]" value="爬山">喝酒
<input type="checkbox" name="hobby[]" value="爬山">网吧
<input type="checkbox" name="hobby[]" value="爬山">打牌<br />
籍贯:
<select name="jiguan">
<option value="021">上海</option>
<option value="011">广州</option>
</select><br />
留言:
<textarea name="words" cols="30" rows="5"></textarea><br />
<input type="submit" name="button" value="提交">
</from>
</body>
</html>
📝文件上传
开发中需要上传图片、音乐、视频等等,这种上传传递是二进制数据。
客户端上传文件
文件域
<from method="post" action="" enctype='下面三个值'>
<input type="file" name="文件类别">
</from>
表单的enctype属性
默认情况下,表单传递是字符流,不能传递二进制流,通过设置表单的enctype属性传递复合数据。enctype属性的值有
1、application/x-www-form-urlencoded
:【默认】,表示传递的是带格式的文本数据
2、multipart/form-data
:复合的表单数据(字符串,文件),文件上传必须设置此值
3、text/plain
:用于向服务器传递无格式的文本数据,主要用户电子邮件
单词:multipart:复合
form-data:表单数组
服务器接受文件
超全局变量$_FTLES
是一个二维数组,用来保存客户端上传到服务器的文件信息。二维数组的行是文件域的名称,列有5个。
1、$_FILES[]['name']
:上传的文件名
2、$_FILES[]['type']
:上传的类型,这个类型是MIME类型 ( image/jpeg、image/gif、image/png)
3、$_FILES[]['size']
:文件的大小,以字节为单位
4、$_FILES[]['tmp_name']
:文件上传时的临时文件
5、S_FILES[][ 'error']
:错误编码(值有:0、1、2、3、4、6、7)0表示正确
S_FILES[][ 'error']
详解
值 | 错误描述 |
---|---|
0 | 正确 |
1 | 文件大小超过了php.ini中允许的最大值upload_max_filesize = 2M |
2 | 文件大小超过了表单允许的最大值 |
3 | 文件大小超过了表单允许的最大值 |
4 | 没有文件上传 |
6 | 找不到临时文件 |
7 | 文件写入失败 |
⭕注意:MAX_FILE_SIZE
必须在文件域的上面
将文件移动到指定位置
函数
move_uploaded_file('临时地址','目标地址');
实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<?php
if(!empty($_POST)){
if($_FILES['face']['error']==0){ // 上传正确
// 文件上传
move_uploaded_file($_FILES['face']['tmp_name'],'./'.$_FILES['face']['name']);
}else {
echo '上传错误';
echo '错误代码:'.$_FILES['face']['error'];
}
}
?>
<from method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</from>
</body>
</html>
⭕注意:上传的同名文件会被覆盖
与文件上传的有关配置
post_max_size = 8M
:表单允许的最大值
upload_max_filesize = 2M
:允许上传的文件大小
upload_tmp dir =F:lwampltmp
:指定临时文件地址,如果不知道操作系统指定
file_uploads = On
:是否允许文件上传
max_file_uploads = 20
∶允许同时上传20个文件
优化文件上传
更改文件名
通过时间戳做文件名
<?php
$erhe='XXX.XXX.jpg';
// echo strrchr($erhe,'.'); // 从最后一个点开始截取。一直截到最后
// rand(100,999) // 生成100-999之间的随机数
echo time().rand(100,999).strrchr($erhe,'.');
?>
通过uniqod()
做文件名
<?php
$erhe='face.stu.jpg';
echo uniqid().strrchr($erhe,'.'),'<br>'; // 生成唯一的ID
echo uniqid('XXXX').strrchr($erhe,'.'),'<br>'; // 带有前缀
echo uniqid('XXXX',true).strrchr($erhe,'.'),'<br>'; // 唯一ID+随机数
?>
验证文件格式
方法一:判断文件的扩展名(不能识别文件伪装)
操作思路:将文件的后缀和允许的后缀对比
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<?php
if(!empty($_POST)){
$allow=array('.jpg','.png','.gif'); // 允许的扩展名
$ext=strrchr($_FILES['face']['name'],'.'); // 上传文件扩展名
if(in_array($ext,$allow))
echo '允许上传';
else {
echo '文件不合法!';
}
}
?>
<from method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</from>
</body>
</html>
⭕注意:比较扩展名不能防止文件伪装
方法二:判断mime类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<?php
if(!empty($_POST)){
$allow=array('image/jpge','image/png','image/gif'); // 允许的扩展名
$mime=$_FILES['face']['type']; // 上传文件扩展名
if(in_array($mime,$allow))
echo '允许上传';
else {
echo '文件不合法!';
}
}
?>
<from method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</from>
</body>
</html>
⭕注意:判断mime不能防止文件伪装
方法三、php_fileinfo扩展(可以防止文件伪装)
在php.ini中开启fileinfo扩展
extension=php_fileinfo.dll
⭕注意:开启fileinfo扩展以后,就可以使用finfo_*
的函数了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<?php
if(!empty($_POST)){
// 第一步:创建finfo资源
$info=finfo_open(FILEINFO_MIME_TYPE);
// 第二步:将finfo资源和文件进行比较
$mime=finfo_file($info,$_FILES['face']['tmpp_name']);
// 第三步:比较是否合法
$allow=array('image/jpge','image/png','image/gif');
echo in_array($mime,$allow)?'合法':'不合法';
}
?>
<from method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</from>
</body>
</html>
实例
步骤:
- 第一步:验证是否有误
- 第二步:验证格式
- 第三步:验证大小
- 第四步:验证是否是http上传
- 第五步:上传实现
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<?php
function check($file){
// 1、验证文件是否有误
if ($file['error'] != 0) {
switch ($file['error']) {
case 1:
return '文件大小超过了php.ini中允许的最大值:' . ini_get('upload_max_filesize');
case 2:
return '文件大小超过了表单允许的最大值';
case 3:
return '文件大小超过了表单允许的最大值';
case 4:
return '没有文件上传';
case 6:
return '找不到临时文件';
case 7:
return '文件写入失败';
default:
return '未知错误';
}
}
// 2、验证格式
$info = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($info, $file['tmp_name']);
$allow = array('image/jpeg', 'image/png', 'image/gif'); // 允许的文件类别
if (!in_array($mime, $allow)) {
return '只能上传' . implode(',', $allow) . '格式';
}
// 3、验证大小
$size = 123456789;
if ($file['size'] > $size) {
return '文件大小不能超过' . number_format($size / 1024, 1) . 'k';
}
// 4、验证是否是http上传
if (!is_uploaded_file($file['tmp_name']))
return '文件不是HTTP POST上传的 <br>';
return null; // 没有错误
}
// 表单提交
if (!empty($_POST)){
// 上传文件过程中有错误显示错误
if ($error=check($_FILES['face'])){
echo $error;
}else{
// 文件上传,上传的文件保存到当前的文件夹中
$foldername=date('Y-m-d'); // 文件夹的名称
$folderpath="./uploads/{$foldername}"; // 文件夹的路径
if(!is_dir($folderpath))
mkdir($folderpath);
$filename=uniqid('',true).strrchr($_FILES['face']['name'],'.'); // 文件名
$filepath="$folderpath/$filename"; // 文件路径
if (move_uploaded_file($_FILES['face']['tmp_name'],$filepath))
echo "上传成功,路径是:{$foldername}/{$fliename}";
else
echo '上传失败<br>';
}
}
?>
<from method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</from>
</body>
</html>
小结:
1、将时间戳转换格式
echo date('Y-m-d H:i:s',1231346),'<br>'; // 将时间戳转换成年-月-日 小时:分钟:秒
echo date('Y-m-d H:i:s'),'<br>'; // 将时间戳转换成年-月-日 小时:分钟:秒
2、设置时区(更改php.ini
)
date.timezone = PRC // PRC:中华人民共和国
3、PHP的执行可以不需要Apache的参与
📣特别声明
原文地址:入坑PHP(二) - 开摆工作室博客 (kbai.cc)
此文章全部都是依靠自己的学习理解来写的原创文章,难免可能会出现有错误的地方,
如果大家以后阅读的时候发现有问题,那就麻烦到下方评论区来进行错误指出,使错误尽快做出改正,
在此,感谢大家的阅读与支持!🤝💦🎉
🍻支持一下
觉得我写的好的话可以支持一下我哦~持续关注我,会更新其他好玩且实用的项目。
👋如果我能帮助到你,那就请我喝杯🧋呗~👇👇👇
我的博客链接:blog.kbai.cc