今天,学习了上传功能,还有具体学习了类与对象,类中的对象属性,对象方法,构造方法,子类及其继承 还有一个小案例。
一、上传功能
首先构建前端页面,这里需要一个表单 ,方法是post,因为上传内容一般都大,然后用了特殊的上传格式enctype="multipart/form-data"。其次,用php处理,上传之后,文件的相关信息都在$_FILE中。具体步骤:
1、检测是否是post方法
2、设置允许的文件类型 将$_FILE中的type tmp_name name error分别赋给变量
3、判断如果文件的类型在预设的文件类型数组中,那么在看把临时文件移到了制定的文件夹中的话就输出上传成功;
4、如果不再支持的文件类型数组中,那么就输出文件类型不支持
5、如果$error大于0 那么代表上传出错 那么输出上传出错
代码
<?php
echo '<pre>',print_r($_FILES, true);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// 设置文件允许的类型
$allowed = ['image/jpeg', 'image/JPG', 'image/png'];
$type = $_FILES['user_pic']['type'];
$tmpName = $_FILES['user_pic']['tmp_name'];
$name = $_FILES['user_pic']['name'];
if (in_array($type, $allowed)) {
if (move_uploaded_file($tmpName, './upload/'.$name)) {
echo "<script>alert('上传成功')</script>";
}
} else {
echo "<script>alert('不支持的文档类型!')</script>";
}
$error = $_FILES['user_pic']['error'];
if ($error > 0) {
echo "<script>alert('上传失败')</script>";
}
}
?>
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input type="file" name="user_pic" id="user_pic">
<!-- 将文件的大小设置在隐藏域里传递给php处理-->
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
<button id="btn">上传</button>
</form>
</body>
</html>点击 "运行实例" 按钮查看在线实例
还有用ajax的方式代码,自己没做 日后参考
<?php
// 设置允许的文件类型
$allowed = ['image/jpeg','image/JPG','image/png'];
// 确保用户执行了上传操作,再执行以下代码
if (isset($_FILES['user_pic'])) {
// 上传的文件类型
$type = $_FILES['user_pic']['type'];
// 临时文件名
$tmpName = $_FILES['user_pic']['tmp_name'];
// 上传的原始文件名
$name = $_FILES['user_pic']['name'];
// 上传的图片地址
$imgFile = 'uploads/' . $name;
// 确保用户上传的类型是图片
if (in_array($type, $allowed)) {
if (move_uploaded_file($tmpName, 'uploads/'.$name)) {
// 如果上传成功,除返回提示信息外,还要返回文件名,用于在客户端预览图片
exit(json_encode(['status'=>1,'message'=>'上传成功','img_url'=>$imgFile]));
}
} else {
exit(json_encode(['status'=>0,'message'=>'类型错误']));
}
// 错误处理, 0 表示无错误,大于0即表示有错误,对于具体类型可以暂不作判断,感兴趣查阅手册
$error = $_FILES['user_pic']['error'];
if ($error > 0) {
exit(json_encode(['status'=>-1,'message'=>'上传失败']));
}
}
?>
<!--以上是前端页面部分-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>异步文件上传</title>
</head>
<body>
<h3>上传用户头像</h3>
<!--因为是异步提交,通过js发送http请求,不再需要设置form属性-->
<p>选择头像:<input type="file" name="user_pic" id="user_pic"></p>
<p><button id="btn">上传</button><span id="tips"></span></p>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
// 因为支持多文件上传,所以用files[0]获取第一个,其实就是单文件上传
var file = document.getElementById('user_pic').files[0];
// 通过FormData()对象获取用户提交的表单数据
var form = new FormData();
// append()可以将表单控制内容添加到对象属性中, 属性用name的值
form.append('user_pic', file);
// 创建Ajax请求对象
var request = new XMLHttpRequest();
// 监听请求过程, 设置成功回调
request.onreadystatechange = function () {
if (request.readyState === 4) {
// console.log(request.responseText);
// 解析服务器端返回的JSON数据
var data = JSON.parse(request.responseText);
// 获取占位符元素
var tips = document.getElementById('tips');
// 根据返回类型,确定应该执行的操作
switch (data.status) {
// 1: 表示上传成功,除提示信息外, 还要显示预览小图片
case 1:
tips.style.color = 'green';
tips.innerHTML = '<img src="'
+data['img_url']
+'" alt="用户头像" width="80">'
+data.message;
break;
// 对于0,1,可以集中处理,因为他们都是出错信息,样式也一样
case 0:
case -1:
tips.style.color = 'red';
tips.innerText = data.message;
break;
// 如果错误信息未在上述情形中,则认为是未知错误
default:
tips.innerText = '未知错误';
}
}
};
// 设置请求参数,直接提交到当前页面处理, true 表示异步,可以省略
request.open('post', '<?=$_SERVER['PHP_SELF']?>',true);
// 使用FormDate,不要设置请求头
// request.setRequestHeader('content-type','application/x-www-form-urlencoded');
// 将Ajax请求发送到服务器端指定php脚本处理,当前就是本页面
request.send(form);
}
</script>
</body>
</html>点击 "运行实例" 按钮查看在线实例
二、类、对象
类就是生成对象的代码模版,对象就是实例化类,也就是把类具体化,比如,美女就是类,那么想冰冰 啵啵 这些就是具体化的美女 就是对象。由同一类实例化的各个对象都是不同的个体,他们彼此不相等。可以用instanceof 来判断是不是实例化自该类。
<?php
// 类是生成对象的代码模版
class demo01
{
}
//对象:类的实例化,是类的具体的实例
//例如:将美女作为类的话,那么对象就有可能是冰冰 啵啵 凤姐等具体的个体
$obj1 = new demo01();
$obj2 = new demo01();
$obj3 = new demo01();
//虽然这三个对象都是由同一个类实例化的结果,但是这三个对象是三个独立的个体,有不同的id;
var_dump($obj1);
echo '<hr>';
var_dump($obj2);
echo '<hr>';
var_dump($obj3);
echo '<hr>';
//检测一个对象是不是这个类的实例
var_dump($obj1 instanceof demo01);
echo '<hr>';
var_dump($obj2 instanceof demo01);
echo '<hr>';
var_dump($obj3 instanceof demo01);
echo '<hr>';
//同一个类实例化的对象不相等
var_dump($obj1 === $obj2);
echo '<hr>';
var_dump($obj2 === $obj3);
/*用id区分对象是我们自己判断的系统并不认,那如何区别呢?
只有通过给不同的对象不同的属性值来区别*/点击 "运行实例" 按钮查看在线实例
三、类的对象属性
由同一类实例化的对象们怎么区分?可以用每个对象不同的属性来区分
对象属性,顾名思义是对象后才可以调用,他基本同变量相同,区别是前面需要家访问限定符,public private proteced,他的作用就是设定作用域
类实例化成对象之后,也可以通过对象添加属性,这就是动态属性,动态属性必然是public 只能通过对象访问,且没有代码错误提示
<?php
/*类中的属性,也叫成员变量,他与变量基本差不多,但是有区别
在类中声明变量属性时,需要访问限定符,他是用来限定属性的作用域的
属性声明时,只能是常量而不能是运算符
public 是访问限定符,他可以在类内类外子类访问*/
class demo02
{
// 对象属性,因为只有对象才能访问
// 初始化并且给定了初始值
public $product = '手机';
public $price = 2800;
}
//类外
//实例化
$obj = new demo02();
//类外访问属性
echo '品名:'.$obj->product.', 价格:'.$obj->price;
echo '<hr>';
//动态属性
//类的属性除了在类内设定也可以在类外添加
$obj->brand = '华为';
echo '手机***是:'.$obj->brand;
echo '<hr>';
//动态属性必然是对象属性,因为只能通过对象访问
//动态属性必然是public,因为是在类外部添加的
//因为不是在类内声明的,所以编辑器不会由错误提示
//get_class_vars 返回类中声明的public属性组成的数组
$array = get_class_vars('demo02');
echo '<pre>', print_r($array, true);
//每次查看类中的属性都需要大量的代码拼接,
//如何才能在类中内部进行数据处理
//对象方法可以实现点击 "运行实例" 按钮查看在线实例
四、对象方法
对象方法可将对象属性这些数据集中在内部处理
对象方法就是对象才能调用,也需要访问限定符,可以传参,在类内部self代表类本身,$this就是值的实例化的对象在类中的相对于占位符的意思
<?php
//对象方法即只有对象才能调用的方法
//对象方法与函数基本一直 只是多了访问限制符
//对象方法调用时同函数一致,方法名后面加上(),也可以传参
class demo03
{
public $product = '手机';
public $price = 2800;
public function getInfo1()
{
// self 当前类
$obj = new self();
echo '品名:'.$obj->product.', 价格:'.$obj->price;
}
public function getInfo2()
{
// 系统早就设定好了一个变量$this,用来代替类实例化后的对象,然后调用类里面属性或者方法的那个对象
$this->price = 1200;
echo '品名:'.$this->product.',价格:'.$this->price;
}
}
$obj = new demo03();
$obj->getInfo1();
echo '<hr>';
$obj->getInfo2();
echo '<hr>';
//查看类中定义的对象方法 只有public才能显示
$method = get_class_methods('demo03');
print_r($method);点击 "运行实例" 按钮查看在线实例
五、构造方法
构造方法是类中的特殊的方法,他随着类的实例化自动执行,通常用来初始化类中的内部对象属性,案例是常用的连接数据的类
<?php
//构造方法是一种特殊的类中的方法,他在类被实例化是自动执行,可用来作为初始化类中的成员
class demo04
{
public $product;
public $price;
// 构造函数
public function __construct($product, $price)
{
$this->product = $product;
$this->price = $price;
}
public function getInfo()
{
echo '品名:'.$this->product.',价格:'.$this->price;
}
}
//实例化自动执行构造函数
$obj = new demo04('电脑', 5888);
$obj->getInfo();
//案例:用构造函数连接数据库
class Db
{
// 初始化连接数据库的3个参数
public $dns;
public $user;
public $password;
// 初始化pdo对象
public $pdo;
// 连接数据库的对象方法
public function connect(){
$this->pdo = new PDO($this->dns, $this->user, $this->password);
}
// 构造函数初始化属性
public function __construct($dns, $password, $user)
{
$this->dns = $dns;
$this->user = $user;
$this->password = $password;
// 自动连接数据库
$this->connect();
}
}
//测试是否连接
$db = new Db('mysql:dbname=php', 'root', 'root');
if ($db->pdo) {
echo'连接成功';
}
//打印数据进行测试
$stmt = $db->pdo->prepare('SELECT * FROM `staff`');
$stmt->execute();
$staffs = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($staffs as $staff) {
print_r($staff); echo '<br>';
}点击 "运行实例" 按钮查看在线实例
六、子类
子类继承父类的所有属性 方法 构造方法,还可以扩展父类的功能,重构方法 构造方法。需要注意 parent::方法名 可以直接继承方法
<?php
class demo05
{
public $product;
public $price;
// 构造函数
public function __construct($product, $price)
{
$this->product = $product;
$this->price = $price;
}
public function getInfo()
{
echo '品名:'.$this->product.',价格:'.$this->price;
}
}
//子类继承自父类demo05 可以使用父类的方法属性
class sub1 extends demo05 {
}
$obj = new sub1('手机', '2800');
$obj->getInfo(); echo '<hr>';
//子类继承父类 增加属性和方法 扩展功能
class sub2 extends demo05
{
public $num;
// 子类构造方法
public function __construct($product, $price, $num)
{
parent::__construct($product, $price);
$this->num = $num;
}
// 扩展功能
public function total() {
return $this->price * $this->num;
}
}
$sub2 = new sub2('手机', '3400', 5);
echo $sub2->getInfo().'总价是:'.$sub2->total().'<hr>';
//方法重写 sub3继承自sub2 由继承自demo05 都能使用和改写他们的方法
class sub3 extends sub2
{
public function total()
{
$total = parent::total(); // TODO: Change the autogenerated stub
switch (true) {
case ($total >= 10000 && $total < 20000):
$discountRate = 0.98; // 98折
break;
case ($total > 20000 && $total < 40000):
$discountRate = 0.88; // 88折
break;
case ($total > 40000 && $total < 60000):
$discountRate = 0.78; // 78折
break;
case ($total >= 60000):
$discountRate = 0.68; // 68折
break;
default:
$discountRate = 1;
}
// 结果四舍五入,保留2位小数
return round($total*$discountRate, 2);
}
}
//实例化
$sub3 = new sub3('电脑', 2800, 15);
echo $sub3->getInfo().' 数量'.$sub3->num.' 折扣价:'.$sub3->total();点击 "运行实例" 按钮查看在线实例
总结
1、上传功能需要前端现构建表单,提交方法post enctype都是固定的,input类型是file,同时也可以用ajax方式 ,这种方法不需要设置form
2、类实例化的对象都是不同的个体,并不相等
3、类的对象属性和对象方法都有作用域,用访问限定符来设置
4、构造函数随着实例化自动执行,通常来初始化类中的属性等内部成员
5、子类突出的特点就是继承可以用父类的属性 方法,可以扩展功能,利用父类的数据增加方法,还可以修改父类的方法,需要注意,子类继承方法用parent::方法名 方便快速 不可缺少
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号