PHP基础2(流程控制,函数)

发布于:2025-06-27 ⋅ 阅读:(13) ⋅ 点赞:(0)

一.前言

本章节继续来讲解php,前面讲解了一些php的基础语法,本章节继续来讲解一下php,主要是来讲解php中的流程控制和函数。

二.流程控制

2.1 if

<?php
header("Content-Type: text/html; charset=utf-8");
$a = rand(1, 10);
if ($a > 5) {
    echo "随机点数比较大";
}
echo "<br>";
echo "当前的点数是" . $a;
?>

2.2 else 

<?php
header("Content-Type: text/html;charset=utf-8");
$user = $_POST["username"];
$pass = $_POST["password"];
if ($user == 'admin' and $pass == '123456'){
    echo "登录成功";
}else{
    echo "登录失败";
}
?>

当然这个需要我们写一个form表单来实现前后端交互 

2.3 elseif/else if 

<?php

$jixiao = 'F';  // 绩效等级初始化

if ($jixiao == 'A') {
    echo "发放1.2倍薪资";
} elseif ($jixiao == 'B') {
    echo "正常发放薪资";
} elseif ($jixiao == 'C') {
    echo "发放90%薪资";
} else {
    echo "发放80%薪资";  // 当前执行分支
}

?>

2.4 while 

条件不成立,一次都不执行

<?php

$i = 1;
while ($i <= 10) {
    
    echo '哈哈'.$i.'次'.'<br>';
    $i++;

}

?>

2.5 do-while 

条件不成立,也会执行一次

<?php
$i = 0;          // 初始化计数器为0
do {
    echo $i;     // 先执行输出(此时$i=0)
} while ($i > 0);// 后检查条件(0>0为false)




?>


2.6 for 

有限循环

<?php
#$i=1初始值,$i<=10 条件,$i++每次加1
    for ($i = 1; $i <= 10; $i++) {
        echo $i;
    }

?>


2.7 foreach 

遍历数组

<?php
# 属组的索引默认是从0开始的数字,也可以自行指定索引
$cars = array(
    "特等奖" => "布加迪",
    "一等奖" => "捷豹",
    "二等奖" => "法拉利",
    "三等奖" => "玛莎拉蒂"
);

foreach ($cars as $key => $value) {
    echo "<tr><td>$key</td><td></td><td>$value</td><td></tr>";
}
?>

2.8 break 打断

打断循环;结束循环

<?php
$cars = array(
    "特等奖" => "布加迪",
    "一等奖" => "捷豹",
    "二等奖" => "法拉利",
    "三等奖" => "玛莎拉蒂",
    "四等奖" => "迈凯伦"
);

foreach ($cars as $key => $value) {
    if ($key == '三等奖') {
        break;
    } else {
        echo $key."是".$value."<br>";
    }
}
?>

2.9 continue 继续 

跳出本轮,开始下一轮

<?php
$cars = array(
    "特等奖" => "布加迪",
    "一等奖" => "捷豹",
    "二等奖" => "法拉利",
    "三等奖" => "玛莎拉蒂",
    "四等奖" => "迈凯伦"
);

foreach ($cars as $key => $value) {
    if ($key == '三等奖') {
        continue;
    } else {
        echo $key."是".$value."<br>";
    }
}
?>

2.10 switch

条件判断

<?php
$a = 5;
$b = 10;
$c = 4;

switch ($c) {
    case 1:
        echo "$a + $b = " . ($a + $b) . "<br>";
        break;
    case 2:
        echo "$a - $b = " . ($a - $b) . "<br>";
        break;
    case 3:
        echo "$a * $b = " . ($a * $b) . "<br>";
        break;
    case 4:
        echo "$a / $b = " . ($a / $b) . "<br>";
        break;
    default: // 条件都不成立时执行
        echo '原来啥也不是';
        break;
}
?>

三.PHP的函数 

介绍:

函数的英文叫作:function,而function的解释项中有另外一个含义:功能,函数就是功能,比如我们 发微信,可能发微信这个后台代码逻辑就是一个函数,将整体的发微信的逻辑代码封装到了函数中,调 用并执行这个函数,就能够实现发微信的动作。

3.1 语法 

<?php
header("Content-Type: text/html;charset=utf-8");

// 欢迎函数
function welcom() {
    echo "欢迎光临!";
}

// 调用欢迎函数
welcom();

echo '<br>做一下加法计算!<br>';

// 第一个add函数(直接输出版)
function add($a, $b) {
    $c = $a + $b;
    echo '加法计算结果为:'.$c.'<br>';
}

// 调用第一个add函数
add(3, 4);
echo '计算结束...<br>';

// 第二个add函数(返回值版)
function add1($a, $b) {
    $c = $a + $b;
    return $c;
}

// 调用第二个add函数
$ret = add1(3, 4);
echo $ret.'<br>';
echo '计算结束...<br>';
?>

3.2 内置函数 

3.2.1 文件包含的函数 

根据您提供的PHP文件包含函数对比表格,以下是核心知识点总结:

📌 PHP文件包含函数对比表

函数 包含失败时的表现 主要特点
include 返回警告 脚本继续执行,适合动态包含(如根据条件包含不同文件)
require 产生致命错误 脚本终止执行,适合包含核心文件(如数据库配置等必须文件)
include_once 返回警告 在include基础上增加重复包含检查,避免函数/类重定义
require_once 产生致命错误 在require基础上增加重复包含检查,适合必须且只需包含一次的重要文件

🔍 使用建议:

  1. 动态内容包含 → 选择include(如:include 'header_'.$lang.'.php'
  2. 关键文件包含 → 选择require(如:require 'database_config.php'
  3. 避免重复包含 → 带_once版本(特别是类和函数定义文件)

💡 典型应用场景:

// 场景1:模板系统(允许失败)
include 'templates/'.$_GET['page'].'.php';

// 场景2:数据库配置(必须成功)
require 'config/database.php';

// 场景3:函数库(只需加载一次)
require_once 'lib/functions.php';

⚠️ 注意:

  • 包含路径建议使用__DIR__绝对路径(如:require __DIR__.'/config.php'
  • 生产环境应关闭错误显示,改用错误日志记录包含失败情况

3.2.2 数学常用函数

我们简单学几个即可:abs()、ceil()、floor()、round()、max()、min()、rand()。 ​

函数名 描述 实例 输入参数 输出结果
abs() 求绝对值 $abs = abs(-4.2); // 4.2 数字(整型/浮点) 绝对值数字
ceil() 进一法取整 echo ceil(9.001); // 10 浮点数 向上取整后的整数
floor() 舍去法取整 echo floor(9.999); // 9 浮点数 向下取整后的整数
fmod() 浮点数取余 $r = fmod(5.7, 1.3); // 0.5 被除数, 除数(x>y) 浮点余数
pow() 返回数的n次方 echo pow(-1, 20); // 1 基数, 指数 乘方值
round() 浮点数四舍五入 echo round(1.95583, 2); // 1.96 数值, [可选精度] 按精度舍入后的结果
sqrt() 求平方根 echo sqrt(9); // 3 被开方数(≥0) 平方根值
max() 求最大值 echo max(1,3,5,6,7); // 7 数字或数组 最大值
min() 求最小值 echo min([2,4,5]); // 2 数字或数组 最小值
mt_rand() 生成更好的随机数 echo mt_rand(0,9); // 0~9随机整数 [最小值], 最大值 范围内的随机整数
rand() 生成随机数 echo rand(); // 随机整数 [最小值], 最大值 随机整数
pi() 获取圆周率值 echo pi(); // 3.1415926535898 圆周率常量

3.2.3 字符串常用函数​

​1. 基础处理​

函数名 描述 示例
trim() 删除两端空格/指定字符 $str="\nHello \n"; echo trim($str); → "Hello"
ltrim() 删除左侧空格/指定字符 echo ltrim("\tHello"); → "Hello"
rtrim() 删除右侧空格/指定字符 echo rtrim("Hello \n"); → "Hello"
strlen() 返回字符串长度 echo strlen("中文"); → 6 (字节数)
mb_strlen() 多字节字符串长度 echo mb_strlen("中文","UTF-8"); → 2
strrev() 反转字符串 echo strrev("Hello"); → "olleH"

​2. 大小写转换​

函数名 描述 示例
strtolower() 转为小写 echo strtolower("HELLO"); → "hello"
strtoupper() 转为大写 echo strtoupper("hello"); → "HELLO"
ucfirst() 首字母大写 echo ucfirst("hello"); → "Hello"
ucwords() 每个单词首字母大写 echo ucwords("hello world"); → "Hello World"

​3. 截取与分割​

函数名 描述 示例
substr() 截取字符串 echo substr("Hello",1,3); → "ell"
mb_substr() 多字节安全截取 echo mb_substr("中文",0,1,"UTF-8"); → "中"
str_split() 将字符串转为数组 print_r(str_split("Hi",1)); → Array([0]=>'H',[1]=>'i')
explode() 按分隔符拆分字符串 print_r(explode(",","a,b,c")); → Array([0]=>'a',[1]=>'b',[2]=>'c')
implode() 将数组连接成字符串 echo implode("-",[1,2,3]); → "1-2-3"
chunk_split() 按长度分割字符串 echo chunk_split("123456",2,"-"); → "12-34-56-"

​4. 查找与替换​

函数名 描述 示例
strpos() 查找首次出现位置(区分大小写) echo strpos("Hello","e"); → 1
stripos() 查找首次位置(不区分大小写) echo stripos("Hello","E"); → 1
str_replace() 替换字符串(区分大小写) echo str_replace("a","*","abc"); → "*bc"
str_ireplace() 替换字符串(不区分大小写) echo str_ireplace("A","*","abc"); → "*bc"
substr_replace() 替换子串 echo substr_replace("world","Hello ",0,0); → "Hello world"
substr_count() 统计子串出现次数 echo substr_count("abab","ab"); → 2

​5. 编码与安全​

函数名 描述 示例
htmlentities() 转义HTML实体 echo htmlentities("<div>"); → "<div>"
htmlspecialchars() 转义特殊字符 echo htmlspecialchars("'"); → "'"
addslashes() 转义引号 echo addslashes("I'm"); → "I'm"
stripslashes() 去除转义符 echo stripslashes("I\'m"); → "I'm"
md5() 生成MD5哈希 echo md5("123"); → "202cb962ac59075b964b07152d234b70"
iconv() 字符编码转换 echo iconv("GBK","UTF-8","中文"); → UTF-8编码的中文字符

​6. 多字节字符串处理​

函数名 描述 示例
mb_strlen() 安全获取字符串长度 echo mb_strlen("中文","UTF-8"); → 2
mb_substr() 安全截取多字节字符串 echo mb_substr("中文",0,1,"UTF-8"); → "中"
mb_http_output() 设置HTTP输出编码 mb_http_output("UTF-8");
mb_check_encoding() 验证编码有效性 var_dump(mb_check_encoding("中文","GB2312")); → bool(true/false)

3.2.4 时间日期函数 

中国的时区在东八区。时间相关函数:date()、getdate()、time(),我们就说一下这三个吧。 



<!--$d = date('Y-m-d H:i:s'); # 格式化时间日期的-->
<!--$d = date('Y-m-d H:i:s', 1661910865); # 通过某个时间戳来格式化时间-->
<!--$t = time(); # 获取当前时间戳-->

<?php
// 时区的报错,修改php.ini,date.timezone = Asia/Shanghai
$mytime = getdate(); // 得到当前时间日期的一个属组
// $mytime = getdate(1661910865); // 通过时间戳获取日期属组(注释状态)

echo "年 :".$mytime['year']."<br>";
echo "月 :".$mytime['mon']."<br>";
echo "日 :".$mytime['mday']."<br>";
echo "时 :".$mytime['hours']."<br>";
echo "分 :".$mytime['minutes']."<br>";
echo "秒 :".$mytime['seconds']."<br>";
echo "一个小时中的第几钟 :".$mytime['minutes']."<br>";
echo "这是一分钟的第几秒 :".$mytime['seconds']."<br>";
echo "星期名称 :".$mytime['weekday']."<br>";
echo "月份名称 :".$mytime['month']."<br>";
echo "时间戳 :".$mytime[0]."<br>";
?>

3.2.5 数组常用函数 

主要是数组元素的增删改查操作。

<?php
header("Content-Type: text/html;charset=utf-8"); // 在响应头中添加了content-type:utf-8,header()是php提供的加工响应头键值对的

$a = array('aa', 'bb', 33, 55);
echo $a[0] . '<br>';
echo var_dump($a) . '<br>';
$a[5] = 'kk';
echo var_dump($a) . '<br>';
$a[1] = 'cc';
echo var_dump($a) . '<br>';

// unset()删除
unset($a[1]);
echo var_dump($a) . '<br>';
?>

其他数组常用函数:​

​1. 数组操作基础​

函数名 描述 示例 重要度
unset() 删除指定元素 unset($arr['key']); ★★★
count() 计算数组元素个数 count($arr); ★★★
array_keys() 返回所有键名组成的新数组 array_keys($arr); ★★
array_values() 返回所有值组成的新数组 array_values($arr); ★★

​2. 元素查找判断​

函数名 描述 示例
in_array() 判断值是否存在 in_array('a', $arr);
array_key_exists() 检查键名是否存在 array_key_exists('k',$arr);
array_search() 搜索值并返回对应键名 array_search('v',$arr);

​3. 数组生成与填充​

函数名 描述 示例
range() 生成范围数组 range(1,5); → [1,2,3,4,5]
array_fill() 填充指定长度的数组 array_fill(0,3,'x');
array_combine() 合并两个数组(键+值) array_combine($keys,$vals);

​4. 数组排序​

函数名 排序方式 特点
sort() 值升序(不保键) 重置键名
asort() 值升序(保键) 保持键值对应
ksort() 键名升序排序 按键名字典序
natsort() 自然排序(大小写敏感) 适合含数字的字符串

​5. 高级操作​

函数名 描述 典型应用
array_slice() 截取数组片段 array_slice($arr,2,3);
array_splice() 替换数组片段 array_splice($arr,1,2,$new);
array_filter() 过滤空值/指定值 array_filter($arr);
array_sum() 计算数值数组的和 array_sum([1,2,3]); → 6

​6. 特殊处理​

函数名 功能 注意点
shuffle() 随机打乱数组 会破坏键名
array_rand() 随机返回键名 返回键名而非值
extract() 将数组键转为变量名 慎用,可能覆盖已有变量

​3.2.6 PHP文件和目录操作

<?php
// readfile() 读取文件内容,并返回文件的长度
$a = readfile('1.txt');
echo '<br>';
echo $a; // 输出文件长度

// 写入数据示例
$a = 'aabbkkdd';
file_put_contents('1.txt', $a); // 没有文件会自动创建

$b = 'ooooo';
file_put_contents('1.txt', $b); // 每次写入新数据都会先清空原文件数据

// 读取文件内容示例
$a = file_get_contents('1.txt');

// 读取远程图片内容(需配置SSL)
$a = file_get_contents('http://www.baidu.com/img/flexible/logo/pc/result.png');

// 配置说明注释:
// 1. windows下的PHP,到php.ini中把 extension=php_openssl.dll 前面的;删掉,重启服务
// 2. linux下的PHP,必须安装openssl模块

// 将远程文件保存到本地(注释状态)
// file_put_contents('1.txt', $a);

echo $a;
?>

3.2.7 fopen 

fopen、fread、fwrite、fclose操作读取文件。

resource fopen ( string $文件名, string 模式)

string fread ( resource $操作资源(也就是文件路径), int 读取长度)

bool fclose ( resource $操作资源 )

注:resource 、string、bool表示的是方法的返回值 。

fopen的模式有下面几个,我们来讲一下fopen的模式: 带+号的先pass ​

模式 读写权限 指针位置 文件不存在时 文件存在时 典型应用场景
r 只读 文件头 返回false 正常打开 读取配置文件、日志分析
r+ 读写 文件头 返回false 正常打开 需要修改文件开头内容
w 只写 文件头 尝试创建 ​清空内容​ 创建新日志文件、覆盖旧数据
w+ 读写 文件头 尝试创建 ​清空内容​ 需要完全重写文件
a 只写(追加) 文件末尾 尝试创建 保留内容,追加写入 日志记录、持续数据收集
a+ 读写(追加) 文件末尾 尝试创建 保留内容,可读可追加 需要读取历史日志并追加新记录
x 只写(独占) 文件头 尝试创建 ​返回false 防止文件覆盖的锁机制
x+ 读写(独占) 文件头 尝试创建 ​返回false 需要独占读写权限的场景

实例:

<?php
// 以只读模式打开文件
$a = fopen('1.txt', 'r');

// 被注释的读取方式(按字节读取)
#$b = fread($a, 18);

// 逐行读取文件内容
$b = fgets($a);
echo $b . "<br>";

// 循环读取剩余内容
while(!feof($a)) {  // !feof($a)表示如果读到文件最后了
    $b = fgets($a);
    echo $b . "<br>";
}

// 尝试写入内容(会失败)
$b = fwrite($a, 'aaaaa'); // 失败返回false,成功返回写入的字符个数
echo $b . "<br>";

// 写入结果判断
if ($b == false) {
    echo '写入失败';  // r模式打开的文件不能写入,r+模式可以写,但是会从文件内容开头覆盖原有内容
}

// 被注释的关闭操作
#fclose($a);
?>

3.2.8 PHP目录处理函数 

 处理文件夹的基本思想如下:

1.读取某个路径的时候判断是否是文件夹

2.是文件夹的话,打开指定文件夹,返回文件目录的资源变量

3.使用readdir读取一次目录中的文件,目录指针向后偏移一次

4.使用readdir读取到最后,没有可读的文件返回false

5.关闭文件目录

 我们来学习一比常用函数:​

函数名 功能描述 返回值 使用示例
scandir() 获取目录下所有文件和子目录 数组(按字母序排序) $items = scandir('/path'); → 包含...的条目数组
opendir() 打开目录句柄 资源类型 $handle = opendir('/path'); → 需配合readdir()使用
readdir() 从目录句柄读取条目 字符串(文件名) while($file=readdir($handle)){...} → 需手动过滤...
is_dir() 判断是否为目录 布尔值 if(is_dir('/path')){...} → 常用于递归遍历时判断
closedir() 关闭目录句柄 closedir($handle); → 防止资源泄漏
filetype() 获取文件类型 'file'或'dir' echo filetype('/path'); → 比is_dir()更直观但性能略低

例如:列举当前目录列表 

<?php
// 获取当前脚本所在目录的绝对路径
$a = dirname(__FILE__);  // 等价于 __DIR__ (PHP 5.3+)
echo '<br>';

// 读取目录内容(包含.和..)
$b = scandir($a);
var_dump($b);  // 打印完整目录数组

// 遍历目录项
foreach ($b as $key => $filename) {
    // 跳过当前目录(.)和上级目录(..)
    if ($filename == '.' || $filename == '..') {
        continue;
    }
    echo $filename . "<br>";  // 输出有效文件名
}

// 检查指定文件类型
filetype($a . '\wp');    // 判断wp文件/目录类型
filetype($a . '\1.txt'); // 判断1.txt文件类型
?>

3.2.9 PHP创建临时文件

我们之前创建的文件都是永久文件。

而创建临时文件在我们平时的项目开发中也非常有用。创建临时文件的几个好处:用完后即删除,不需 要去维护这个文件的删除状态。

<?php
// 创建临时文件(自动生成唯一文件名)
$handle = tmpfile();  // 返回文件句柄资源

// 写入UTF-8数据(1个中文字符占3字节)
$numbytes = fwrite($handle, '写入临时文件');  // 返回写入的字节数

// 调试时可取消注释观察临时文件
// sleep(60);  // 暂停60秒(此时文件可被其他进程查看)

// 关闭即自动删除(无持久化存储)
fclose($handle);

// 输出结果:中文+英文字符共15字节
echo '向临时文件中写入了'.$numbytes.'个字节';
// Windows存储路径:C:\Users\用户名\AppData\Local\Temp\phpXXXX.tmp
?>

3.2.10 PHP移动、拷贝和删除文件 

重命名

我们日常在处理文件的时候,可以删除文件、重命名文件也可以也可复制文件。

我们先来说重命名,重命名的函数是: bool rename($旧名,$新名); ,方法的返回结果是布尔值。

这个函数返回一个bool值,将旧的名字改为新的名字。

<?php
// 定义原始文件名
$filename = 'test.txt';

// 生成新文件名(追加.xx后缀)
$filename2 = $filename . '.xx';

// 重命名文件(同级目录)
rename($filename, $filename2);

// 移动文件到xx目录并重命名
rename($filename, '\\xx\\' . $filename2);
?>

复制文件

复制文件,就相当于是克隆技术,将一个原来的东西再克隆成一个新的东西。两个长得一模一样。 boolcopy(源文件,目标文件) 

功能:将指定路径的源文件,复制一份到目标文件的位置。

我们来通过实验和代码来玩玩:

<?php
// 旧文件名定义
$filename = '1.txt';

// 新文件名生成(追加_new后缀)
$filename2 = $filename . '_new';

// 执行文件复制操作
copy($filename, $filename2);
?>

总结:你会通过上面的例子,发现多出来了一个文件。

删除文件 

删除文件就是将指定路径的一个文件删除,不过这个删除是直接删除。使用的是windows电脑,你在回 收站看不到这个文件。你只会发现,这个文件消失了。 bool unlink(指定路径的文件)

<?php
// 定义要删除的文件名
$filename = '1.txt';

// 执行文件删除操作并返回结果
if (unlink($filename)) {
    echo "删除文件成功 $filename!\n";
} else {
    echo "删除 $filename 失败!\n";
}
?>

检测文件属性 

比如,检测一下xx.txt文件是否存在

<?php
if(file_exists('index.html')) {
    echo '文件已存在';
    exit;
}
?>

常用文件属性函数 

函数名 参数类型 返回值 功能描述 使用示例
file_exists() 字符串(路径) bool 检测文件/目录是否存在 file_exists('/var/www/test.php')
is_readable() 字符串(路径) bool 检测文件是否可读 is_readable('config.ini')
is_writeable() 字符串(路径) bool 检测文件是否可写 is_writeable('log.txt')
is_executable() 字符串(路径) bool 检测文件是否可执行 is_executable('app.sh')
is_file() 字符串(路径) bool 检测是否是普通文件 is_file('data.json')
is_dir() 字符串(路径) bool 检测是否是目录 is_dir('uploads/')
clearstatcache() void 清除文件状态缓存 clearstatcache()

3.2.11 PHP文件权限设置

chmod 主要是修改文件的的权限。主要是针对linux系统的,这个我们前面学过,就不多说了。

<?php
// 修改Linux系统文件权限为755
chmod("/var/wwwroot/index.html", 755);

// 使用符号模式设置权限
chmod("/var/wwwroot/index.html", "u+rwx,go+rx");

// 八进制格式设置权限
chmod("/somedir/somefile", 0755);
?>

3.2.12 PHP文件路径函数 

我们经常会遇到处理文件路径的情况。

例如:

        1.文件后缀需要取出来

        2.路径需要取出名字不取目录

        3.只需要取出路径名中的目录路径

        4.或者把网址中的各个部份进行解析取得独立值

        5.甚至是自己组成一个url出来

        ... .... 

很多地方都需要用路径处理类的函数。

我们把常用的路径处理函数为大家做了标注,大家对着这个路径处理函数进行处理即可:

函数名 功能描述 参数说明 返回值示例
pathinfo() 解析文件路径各组成部分 (路径, [选项]) ['dirname'=>'/a','basename'=>'b.txt']
basename() 提取路径中的文件名 (路径, [后缀过滤]) 'image.jpg'(输入/a/b/image.jpg
dirname() 获取文件所在目录路径 (路径) '/a/b'(输入/a/b/file.txt
parse_url() 分解URL为关联数组 (URL) ['scheme'=>'https', 'host'=>'example.com']
http_build_query() 将数组转换为URL查询字符串 (关联数组) 'name=John&age=30'
http_build_url() 组装URL组件为完整URL (基础URL, 组件数组) 需安装pecl_http扩展

示例,记住示例中的几个即可 

<?php
// 解析文件路径信息
$path_parts = pathinfo('d:/www/index.inc.php');

// 输出各组成部分
echo '文件目录名:' . $path_parts['dirname'] . "<br/>";
echo '文件全名:' . $path_parts['basename'] . "<br/>";
echo '文件扩展名:' . $path_parts['extension'] . "<br/>";
echo '不包含扩展的文件名:' . $path_parts['filename'] . "<br/>";
?>

3.2.13 PHP文件上传

在web常见漏洞中有一个文件上传的漏洞,后面我们会讲到。

在我们日常使用中经常会遇到很多种这样的情况:

QQ空间里面上传图片呀

微信朋友圈上传图片

发邮件里面上传邮件资料附件

认证的时候要求上传照片或身份证 

文件上传需要注意php.ini这个配置文件,这个文件我们在phpstudy中就能看到 

只有 file_uploads = on 时,php才能支持上传文件

phpinfo()函数,也可以看到这些配置信息。

配置项 默认值 推荐值 功能说明 修改建议
file_uploads on on 主开关:on开启文件上传功能,off禁用 生产环境必须保持on
upload_tmp_dir 系统临时目录 自定义路径 存储临时文件的目录(如:C:\Users\用户名\AppData\Local\Temp 建议改为独立目录:
upload_tmp_dir = /var/php_upload_tmp
post_max_size 8M 200M POST请求最大值(必须≥upload_max_filesize 在php.ini中修改:
post_max_size = 200M
upload_max_filesize 2M 100M 单个文件大小限制 需同步调整post_max_size
upload_max_filesize = 100M
memory_limit 128M 256M 脚本内存限制(处理大文件时需增加) 根据服务器配置调整:
memory_limit = 256M

建议尺寸: file_size(文件大小) < upload_max_filesize < post_max_size < memory_limit

另外,需要注意的是脚本执行时间,max_execution_time配置,这个参数的单位为秒。它是设定脚本的 最大执行时间。也可以根据需求做适当的改变。通常不需要来修改,系统默认值即可。超大文件上传的 时候,可能会涉及到这一项参数的修改。上传时间太长了,会超时。如果你将此项参数设为0,则是不限 制超时时间,不建议使用,文件太大了,想别的方式处理,一般会分块传输 。

完成了php.ini的相关配置,我们就可以开始试着完成第一次文件上传了。别忘了重启服务。

通过php获取webserver相关配置信息的代码

<?php
// 设置响应头为UTF-8编码的HTML格式
header("Content-Type: text/html; charset=utf-8");

// 获取服务器和客户端信息
$a = $_SERVER['HTTP_HOST'];       // 获取当前域名
$b = $_SERVER['HTTP_USER_AGENT']; // 获取用户浏览器信息

// 输出信息并换行
echo $a . '<br>';
echo $b . '<br>';
?>

上传文件步骤 

1.系统返回的错误码详解​

错误码 含义 原因分析 解决方案
​0​ 上传成功 文件通过所有验证 可继续执行move_uploaded_file()等后续操作
​1​ 超出upload_max_filesize 文件大小超过php.ini中的全局限制(默认2M) 修改php.ini:
upload_max_filesize = 100M
需同步调整post_max_size
​2​ 超出表单指定大小 超过<input type="file" name="file" max-size="500000">等表单限制 检查前端表单设置或后端验证逻辑
​3​ 部分文件上传 网络中断或浏览器崩溃导致 重新上传或检查网络连接
​4​ 无文件上传 用户未选择文件或表单未设置enctype="multipart/form-data" 检查HTML表单属性:
<form method="post" enctype="multipart/form-data">
​6​ 临时目录缺失 upload_tmp_dir配置错误或权限不足 创建目录并设权限:
mkdir /tmp/uploads; chmod 777 /tmp/uploads
​7​ 写入失败 磁盘空间不足/权限问题/文件名非法 检查磁盘空间:
df -h
确保目标目录可写:
chown -R www-data:www-data /uploads

注:错误码中没有5。

2.自定义判断是否超出文件大小范围

在开发上传功能时。我们作为开发人员,除了php.ini中规定的上传的最大值外。我们通常还会设定一个 值,是业务规定的上传大小限制。

例如:

新浪微博或者QQ空间只准单张头像图片2M。而在上传图册的时候又可以超过2M来上传。

所以说,它的系统是支持更大文件上传的。

此处的判断文件大小,我们用于限制实际业务中我们想要规定的上传的文件大小。 

3.判断后缀名和mime类型是否符合

在网络世界里面也有坏人。他们会把图片插入病毒,在附件中上传病毒,他们会在网页中插入病毒或者 黄色图片。

我们需要对于上传的文件后缀和mime类型都要进行判断才可以。

百度解释:MIME(Multipurpose Internet Mail Extensions)是多用途互联网邮件扩展类型。是设定 某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定 应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

通俗解释: 有兴趣看一看

        其实MIME更像是一种协议。

        首先,我们要了解浏览器是如何处理内容的。在浏览器中显示的内容有 HTML、有 XML、有 GIF、还有Flash ......那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME Type,也就是 该资源的媒体类型。

        媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 ContentType 来表示的,例如:

        Content-Type: text/HTML

        表示内容是 text/HTML 类型,也就是超文本文件。为什么是"text/HTML"而不是"HTML/text"或者 别的什么?MIME Type 不是个人指定的,是经过 ietf 组织协商,以 RFC 的形式作为建议的标准发布在网 上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过MIME Type 指定的)。

        通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的 格式,一般只能以 application/x- 开头。

        XHTML 正是一个获得广泛应用的格式,因此,在 RFC 3236 中,说明了 XHTML 格式文件的 MIME Type 应该是 application/xHTML+XML。

        当然,处理本地的文件,在没有人告诉浏览器某个文件的 MIME Type 的情况下,浏览器也会做一些默 认的处理,这可能和你在操作系统中给文件配置的 MIME Type 有关。

比如在 Windows 下,打开注册表的"HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type"主键,你可以看到所有 MIME Type 的配置信息。

        在把输出结果传送到浏览器上的时候,浏览器必须启动适当的应用程序来处理这个输出文档。这可以通过 多种类型MIME(多功能网际邮件扩充协议)来完成。在HTTP中,MIME类型被定义在Content-Type header中。

        例如,假设你要传送一个Microsoft Excel文件到客户端。那么这时的MIME类型就是"application/vnd.ms-excel"。在大多数实际情况中,这个文件然后将传送给Execl来处理(假设我们设 定Execl为处理特殊MIME类型的应用程序)。在ASP中,设定MIME类型的方法是通过Response对象的ContentType属性。

多媒体文件格式MIME

        最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识 数据类型。

        MIME意为多目Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件 客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输 的不仅是普通的文本,而变得丰富多彩。

        每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的 种类。

常见的MIME类型

        超文本标记语言文本 .html,.html text/html

        普通文本 .txt text/plain

        RTF文本 .rtf application/rtf

        GIF图形 .gif image/gif

        JPEG图形 .ipeg,.jpg image/jpeg

        au声音文件 .au audio/basic

        MIDI音乐文件 mid,.midi audio/midi,audio/x-midi

        RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio

        MPEG文件 .mpg,.mpeg video/mpeg

        AVI文件 .avi video/x-msvideo

        GZIP文件 .gz application/x-gzip

        TAR文件 .tar application/x-tar

        Internet中有一个专门组织IANA来确认标准的MIME类型,但Internet发展的太快,很多应用程序等 不及IANA来确认他们使用的MIME类型为标准类型。因此他们使用在类别中以x-开头的方法标识这个类别还没 有成为标准,例如:x-gzip,x-tar等。事实上这些类型运用的很广泛,已经成为了事实标准。只要客户机和 服务器共同承认这个MIME类型,即使它是不标准的类型也没有关系,客户程序就能根据MIME类型,采用具体 的处理手段来处理数据。而Web服务器和浏览器(包括操作系统)中,缺省都设置了标准的和常见的MIME类 型,只有对于不常见的 MIME类型,才需要同时设置服务器和客户浏览器,以进行识别。

        由于MIME类型与文档的后缀相关,因此服务器使用文档的后缀来区分不同文件的MIME类型,服务器中必 须定义文档后缀和MIME类型之间的对应关系。而客户程序从服务器上接收数据的时候,它只是从服务器接受数 据流,并不了解文档的名字,因此服务器必须使用附加信息来告诉客户程序数据的MIME类型。服务器在发送真 正的数据之前,就要先发送标志数据的MIME类型的信息,这个信息使用Content-type关键字进行定义,例如 对于HTML文档,服务器将首先发送以下两行MIME标识信息,这个标识并不是真正的数据文件的一部分。

        Content-type: text/html

        注意,第二行为一个空行,这是必须的,使用这个空行的目的是将MIME信息与真正的数据内容分隔开。

        MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。官方的 MIME 信息是由 Internet Engineering Task Force (IETF) 在下面的文档中提供的:RFC-822 Standard for ARPA Internet text messages

        RFC-2045 MIME Part 1: Format of Internet Message Bodies

        

        RFC-2046 MIME Part 2: Media Types

        RFC-2047 MIME Part 3: Header Extensions for Non-ASCII Text

        RFC-2048 MIME Part 4: Registration Procedures

        RFC-2049 MIME Part 5: Conformance Criteria and Examples

        

        不同的应用程序支持不同的 MIME 类型。

在判断后缀和MIME类型的时候,我们会用到PHP的一个函数in_array(),该函数传入两个参数。

第一个参数是要判断的值;

第二个参数是范围数组。
我们用这个函数来判断文件的后缀名和mime类型是否在允许的范围内。 

 

4.生成文件名

我们的文件上传成功了,不会让它保存原名。因为,有些人在原名中有敏感关键词会违反我国的相关法 律和法规。我们可以采用date()、mt_rand()或者unique()生成随机的文件名。

5.判断是否是上传文件

文件上传成功时,系统会将上传的临时文件上传到系统的临时目录中。产生一个临时文件。同时会产生 临时文件名。我们需要做的事情是将临时文件移动到系统的指定目录中。而移动前不能瞎移动,或者移 动错了都是不科学的。移动前我们需要使用相关函数判断上传的文件是不是通过 HTTP POST 上传的,is_uploaded_file()传入一个参数($_FILES中的缓存文件名),is_uploaded_file() 函数检查指定的文件是否 是通过 HTTP POST 上传的,如果文件是通过 HTTP POST 上传的,该函数返回 TRUE。

6.移动临时文件到指定位置

临时文件是真实的临时文件,我们需要将其移动到我们的网站目录下面了。让我们网站目录的数据,其 他人可以访问到,我们使用: move_uploaded_file() 。这个函数是将上传文件移动到指定位置,并命名。

需要传入两个参数:

第一个参数是指定移动的上传文件;

第二个参数是指定的文件夹和名称拼接的字符串。

大致步骤 

php文件上传表单注意事项

代码示例

创建index.html文件,内容如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传表单</title>
</head>
<body>
    <h1>上传文件</h1>
    <form action="chuli.php" method="post" enctype="multipart/form-data">
        请选择文件:<input type="file" name="file" />
        <input type="submit" value="上传" />
    </form>
</body>
</html>

注意事项:

1.form 表单中的参数method 必须为post。若为get是无法进行文件上传的

2.enctype须为multipart/form-data

再创建一个php文件,比如叫做chuli.php

<?php
// 获取上传文件信息
$arr = $_FILES["file"];
// var_dump($arr);

// 文件类型与大小限制条件
if(($arr["type"]=="image/jpeg" || $arr["type"]=="image/png") && $arr["size"]<10241000) {
    // 生成唯一文件名(时间戳+原文件名)
    $filename = "./images/".date('YmdHis').$arr["name"];

    // 检查文件是否已存在
    if(file_exists($filename)) {
        echo "该文件已存在";
    } else {
        // 处理中文文件名编码转换
        $filename = iconv("UTF-8","gb2312",$filename);

        // 移动临时文件到目标位置(核心操作)
        move_uploaded_file($arr["tmp_name"], $filename);
        echo "文件上传成功";
    }
} else {
    echo "上传的文件大小或类型不符";
}
?>

3.2.14 php执行系统命令函数 

system('指令')

exec('指令'),这个指令的结果回显不太好,但是指令执行是没问题的。 

四.总结

本章节讲的内容很多,大家吸收消化一下,实在不记得也没啥关系,点赞关注加收藏,遇到的时候再来看就好了啦


网站公告

今日签到

点亮在社区的每一天
去签到