PHP案例 ——音乐列表项目(下)

简介: PHP案例 ——音乐列表项目(下)

音乐列表案例(上)


项目链接: https://download.csdn.net/download/weixin_45525272/14920287


音乐列表案例(下)


2.2. 新增数据(表单类)


表单使用(form action method enctype,input name label for id)服务端表单校验并提示错误消息


empty 判断一个成员是否没定义或者值为 false(可以隐式转换为 false)


  • 上传文件,文件数量,文件种类


// $images['error'] => [0, 0, 0]
if ($images['error'][$i] !== UPLOAD_ERR_OK) {
  $GLOBALS['error_message'] = '上传海报文件失败1';
  return;
}
// 类型的校验
// $images['type'] => ['image/png', 'image/jpg', 'image/gif']
if (strpos($images['type'][$i], 'image/') !== 0) {
  $GLOBALS['error_message'] = '上传海报文件格式错误';
  return;
}
// TODO: 文件大小的判断
if ($images['size'][$i] > 1 * 1024 * 1024) {
  $GLOBALS['error_message'] = '上传海报文件过大';
  return;
}


  • 如果需要考虑文件重名的情况,可以给上传的文件重新命名(唯一名称)


// 移动文件到网站范围之内
$dest = '../uploads/' . uniqid() . iconv('UTF-8', 'GBK', $images['name'][$i]);
// move_uploaded_file 在 Windows 中文系统上要求传入的参数如果有中文必须是 GBK 编码
// 切记在接收文件时注意文件名中文的问题,通过iconv函数转换中文编码为 GBK 编码
if (!move_uploaded_file($images['tmp_name'][$i], $dest)) {
  $GLOBALS['error_message'] = '上传海报文件失败2';
  return;
}
// 存储时候在将GBK编码转换回UTF-8格式   并且去掉文件路径前面的两个点  直接在根目录存储
$data['images'][] = iconv('GBK', 'UTF-8', substr($dest, 2));


  • 单文件域多文件上传,name 一定 以 [] 结尾,服务端会接收到一个数组


html中


<!-- multiple 可以让一个文件域多选 -->
<input type="file" class="form-control" 
id="images" name="images[]" 
accept="image/*" multiple>


php中


$images = $_FILES['images'];
  // 准备一个容器装所有的海报路径
  $data['images'] = array();


  • JSON 序列化文件写入


 // 先读出原有数据,在转化为数组形式  在添加新的数组数据,在将新的数据覆盖以前所有旧的原有数据
$json = file_get_contents('data.json'); 
$old = json_decode($json, true);
array_push($old, $data);
$new_json = json_encode($old);
file_put_contents('data.json', $new_json);


2.3. 删除数据


  • 问号传参(用get:get本身支持url传参形式)


一般情况下,如果需要超链接点击发起的请求可以传递参数,我们可以采用 ? 的方式


<a href="/delete.php?id=123">删除</a>


本案例中,id传的是歌曲的id


<a class="btn btn-danger btn-sm" href="delete.php?id=<?php echo $item['id']; ?>">删除</a>


  • 数组移除元素,array_splice函数


// 从原有数据中移除
$index = array_search($item, $data);
array_splice($data, $index, 1);


3.整体代码


add.php


<?php
function add () {
  // 目标:接收客户端提交的数据和文件,最终保存到数据文件中
  $data = array(); // 准备一个空的容器,用来装最终要保存的 数据
  $data['id'] = uniqid();
  // 1. 接收提交的文本内容
  // ===================================================
  if (empty($_POST['title'])) {
    $GLOBALS['error_message'] = '请输入音乐标题';
    return;
  }
  if (empty($_POST['artist'])) {
    $GLOBALS['error_message'] = '请输入歌手名称';
    return;
  }
  // 记下 title 和 artist
  $data['title'] = $_POST['title'];
  $data['artist'] = $_POST['artist'];
  // 2. 接收图片文件
  // =======================================================
  // 如何接收单个文件域的多文件上传???
  if (empty($_FILES['images'])) {
    $GLOBALS['error_message'] = '请正常使用表单';
    return;
  }
  $images = $_FILES['images'];
  // 准备一个容器装所有的海报路径
  $data['images'] = array();
  // 遍历这个文件域中的每一个文件(判断是否成功、判断类型、判断大小、移动到网站目录中)
  for ($i = 0; $i < count($images['name']); $i++) {
    // $images['error'] => [0, 0, 0]
    if ($images['error'][$i] !== UPLOAD_ERR_OK) {
      $GLOBALS['error_message'] = '上传海报文件失败1';
      return;
    }
    // 类型的校验
    // $images['type'] => ['image/png', 'image/jpg', 'image/gif']
    if (strpos($images['type'][$i], 'image/') !== 0) {
      $GLOBALS['error_message'] = '上传海报文件格式错误';
      return;
    }
    // TODO: 文件大小的判断
    if ($images['size'][$i] > 1 * 1024 * 1024) {
      $GLOBALS['error_message'] = '上传海报文件过大';
      return;
    }
    // 移动文件到网站范围之内
    $dest = '../uploads/' . uniqid() . iconv('UTF-8', 'GBK', $images['name'][$i]);
    // move_uploaded_file 在 Windows 中文系统上要求传入的参数如果有中文必须是 GBK 编码
    // 切记在接收文件时注意文件名中文的问题,通过iconv函数转换中文编码为 GBK 编码
    if (!move_uploaded_file($images['tmp_name'][$i], $dest)) {
      $GLOBALS['error_message'] = '上传海报文件失败2';
      return;
    }
    // 存储时候在将GBK编码转换回UTF-8格式   并且去掉文件路径前面的两个点  直接在根目录存储
    $data['images'][] = iconv('GBK', 'UTF-8', substr($dest, 2));
  }
  // 3. 接收音乐文件
  // =======================================================
  if (empty($_FILES['source'])) {
    $GLOBALS['error_message'] = '请正常使用表单';
    return;
  }
  $source = $_FILES['source'];
  // => { name: , tmp_name .... }
  // 判断是否上传成功
  if ($source['error'] !== UPLOAD_ERR_OK) {
    $GLOBALS['error_message'] = '上传音乐文件失败1';
    return;
  }
  // 判断类型是否允许
  $source_allowed_types = array('audio/mp3', 'audio/wma');
  if (!in_array($source['type'], $source_allowed_types)) {
    $GLOBALS['error_message'] = '上传音乐文件类型错误';
    return;
  }
  // 判断大小
  if ($source['size'] < 1 * 1024 * 1024) {
    $GLOBALS['error_message'] = '上传音乐文件过小';
    return;
  }
  if ($source['size'] > 10 * 1024 * 1024) {
    $GLOBALS['error_message'] = '上传音乐文件过大';
    return;
  }
  // 移动
  $target = '../uploads/' . uniqid() . '-' . iconv('UTF-8', 'GBK', $source['name']);
  if (!move_uploaded_file($source['tmp_name'], $target)) {
    $GLOBALS['error_message'] = '上传音乐文件失败2';
    return;
  }
  // 将数据装起来
  // 保存数据的路径一定使用绝对路径存
  $data['source'] = iconv('GBK', 'UTF-8', substr($target, 2));
  // 4. 将数据加入到原有数据中
  // 先读出原有数据,在转化为数组形式  在添加新的数组数据,在将新的数据覆盖以前所有旧的原有数据
  $json = file_get_contents('data.json'); 
  $old = json_decode($json, true);
  array_push($old, $data);
  $new_json = json_encode($old);
  file_put_contents('data.json', $new_json);
  // 5. 跳转
  // header('Location: list.php');
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  add();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>添加新音乐</title>
  <link rel="stylesheet" href="bootstrap.css">
</head>
<body>
  <div class="container py-5">
    <h1 class="display-4">添加新音乐</h1>
    <hr>
    <?php if (isset($error_message)): ?>
    <div class="alert alert-danger">
      <?php echo $error_message; ?>
    </div>
    <?php endif ?>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
      <div class="form-group">
        <label for="title">标题</label>
        <input type="text" class="form-control" id="title" name="title">
      </div>
      <div class="form-group">
        <label for="artist">歌手</label>
        <input type="text" class="form-control" id="artist" name="artist">
      </div>
      <div class="form-group">
        <label for="images">海报</label>
        <!-- multiple 可以让一个文件域多选 -->
        <input type="file" class="form-control" id="images" name="images[]" accept="image/*" multiple>
      </div>
      <div class="form-group">
        <label for="source">音乐</label>
        <!-- accept 可以设置两种值分别为  MIME Type / 文件扩展名 -->
        <input type="file" class="form-control" id="source" name="source" accept="audio/*">
      </div>
      <button class="btn btn-primary btn-block">保存</button>
    </form>
  </div>
</body>
</html>


delete.php


<?php
// 如何知道客户端想要删除哪一个???
// 通过客户端在URL地址中的问号参数的不同来辨别要删除的数据
// 接收 URL 中的不同的 ID
if (empty($_GET['id'])) {
  // 没有传递必要的参数
  exit('<h1>必须指定参数</h1>');
}
$id = $_GET['id'];
// 找到要删除的数据
$data = json_decode(file_get_contents('data.json'), true);
foreach ($data as $item) {
  // 不是我们要的之间找下一条
  if ($item['id'] !== $id) continue;
  // $item => 我们要删除的那一条数据
  // 从原有数据中移除
  $index = array_search($item, $data);
  array_splice($data, $index, 1);
  // 保存删除指定数据过后的内容
  // echo '<pre>';
  // var_dump($data);
  // echo '</pre>';
  $json = json_encode($data);
  file_put_contents('data.json', $json);
  // 跳转回列表页
  header('Location: list.php');
}
相关文章
|
3月前
|
Web App开发 安全 PHP
刚上线的PHP项目被攻击了怎么办
近期因忙于多个项目,代码质量有所疏忽,导致项目上线后遭攻击。攻击者通过文件上传漏洞和测试登录方式入侵,修改了 index.php 并植入恶意文件。经排查,问题源于未限制上传文件类型及未关闭测试登录配置。修复措施包括锁定文件、限制上传后缀、关闭测试登录、删除高危用户并限制其访问。此次事件提醒我们,细节疏漏可能引发严重风险,需时刻保持警惕。
|
3月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
5月前
|
JavaScript Linux PHP
composer如何安装以及举例在PHP项目中使用Composer安装TCPDF库-优雅草卓伊凡
composer如何安装以及举例在PHP项目中使用Composer安装TCPDF库-优雅草卓伊凡
200 3
composer如何安装以及举例在PHP项目中使用Composer安装TCPDF库-优雅草卓伊凡
|
5月前
|
存储 缓存 安全
php项目源码加密之Zend Guard Loader加密的代码解密可能性很小-优雅草卓伊凡
php项目源码加密之Zend Guard Loader加密的代码解密可能性很小-优雅草卓伊凡
212 2
|
5月前
|
PHP
Composer在PHP项目中的手动类自动加载策略
为了确保文件名和类名的一致性及其可预测性,类名通常应该与文件名相匹配,所有的类都应属于一个命名空间,并且目录结构应该反映命名空间的结构。如此一来,当新的类被创建时,它们会自动遵守已有的约定,从而无需修改自动加载逻辑,确保了代码的模块化和可管理性。
69 8
|
9月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
502 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
6月前
|
安全 API PHP
Composer在现代PHP项目中的进阶实践
简介:本文深入探讨PHP依赖管理工具Composer的核心功能与企业实践。首先介绍其如何通过`composer.json`实现声明式依赖管理,变革PHP生态;接着解析自动加载优化、版本策略(如`~`和`^`)及私有仓库集成等关键特性;然后分享CI/CD集成、多环境配置与性能优化技巧(如阿里云镜像加速)的企业级方案;最后提供常见问题排查方法,如内存不足和依赖冲突解决,助力开发者高效管理项目依赖。
159 3
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
域名解析 关系型数据库 MySQL
基于PHPEnv的本地环境搭建—PHP第一个项目:HelloWorld(从安装到运行)
该文章指导如何使用PHPEnv搭建本地PHP开发环境,并通过一个简单的"Hello World"程序演示从安装到运行的全过程。
基于PHPEnv的本地环境搭建—PHP第一个项目:HelloWorld(从安装到运行)
|
设计模式 数据管理 测试技术
PHP中的设计模式:单一职责原则在实战项目中的应用
在软件开发中,设计模式是解决问题的最佳实践。本文通过分析单一职责原则(SRP),探讨了如何运用这一原则来提升PHP项目的可维护性和扩展性。我们将从实际案例出发,展示单一职责原则在业务逻辑分离、代码解耦和提高测试效率方面的应用。无论是新手还是经验丰富的开发者,都能从中获益,进而编写出更健壮、更灵活的PHP代码。
168 5