PHP在线相册--【白嫖项目】

news2024/10/6 0:32:42

强撸项目系列总目录在000集

PHP要怎么学–【思维导图知识范围】

文章目录

    • 本系列校训
    • 本项目使用技术
  • 上效果图
  • phpStudy 设置
  • 导数据库
  • 项目目录如图:
  • 代码部分:
    • 主页
  • 配套资源
  • 作业:

本系列校训

用免费公开视频,卷飞培训班哈人!打死不报班,赚钱靠狠干!
只要自己有电脑,前后项目都能搞!N年苦学无人问,一朝成名天下知!

本项目使用技术

PHP无类PHP类写法ThinkPHP框架其它框架
*

环境

PHP版本mysql版本运行工具编辑工具
5.4.45+Apache5.5(phpstudy自带)phpstudy2018VSCode

上效果图

在php 当中,上传图片,上传照片这种小功能还是挺方便的。注意没有登陆
所以,在线相册这个小项目还是有一定的价值的。比如某宝(好象人家不会用这么LOW的)那就作业吧

在这里插入图片描述

修改了代码,可以搜索了。
在这里插入图片描述在这里插入图片描述

phpStudy 设置

网站目录,不能有中文或空格,就乖乖的用C语言能识别的变量名

在这里插入图片描述

导数据库

打开mysql-front 或navicat
注意:数据库名:email 超级用户:root 密码:123456
运行本例附件即可。最后导入数据库成功的截图如下:

在这里插入图片描述

项目目录如图:

在这里插入图片描述
颜色主题:
在这里插入图片描述

代码部分:

主页

<?php
require './common/init.php';
// 接收参数
$id = input('get', 'id', 'd');
$sort = input('get', 'sort', 's');
$action = input('post', 'action', 's');
// 判断相册是否存在
if ($id && !album_data($id)) {
    exit('相册不存在!');
}
// 新建相册
if ($action == 'new') {
    album_new($id, input('post', 'name', 's'));
}
// 上传图片
elseif ($action == 'upload') {
    album_upload($id, input($_FILES, 'upload', 'a'));
}
// 删除相册
elseif ($action == 'delete') {
    album_delete(input('post', 'action_id', 'd'));
}
// 设为封面
elseif ($action == 'pic_cover') {
    album_picture_cover(input('post', 'action_id', 'd'), $id);
}
// 删除图片
elseif ($action == 'pic_delete') {
    album_picture_delete(input('post', 'action_id', 'd'));
}
// 查询相册名称作为网页标题
$title = album_data($id)['name'] ?: '首页';
// 查询导航栏
$nav = album_nav($id);
// 查询相册列表
$list = album_list($id, $sort);
// 载入模板
require './view/index.html';

主页的html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title><?=htmlspecialchars($title)?> - 在线相册</title>
    <link rel="stylesheet" href="./css/style.css">
  </head>
  <body>
    <?php require './view/common/top.html'; ?>
    <div class="container">
      <div class="opt">
        <div class="opt-sort">
          <a class="<?=($sort!='old') ? 'curr' : ''?>" href="?id=<?=$id?>">最新的</a>
          <a class="<?=($sort=='old') ? 'curr' : ''?>" href="?id=<?=$id?>&sort=old">最旧的</a>
        </div>
        <div class="opt-new">
          <form method="post">
            <input type="hidden" name="action" value="new">
            <input type="text" name="name" placeholder="输入相册名称" required><input type="submit" value="创建相册">
          </form>
        </div>
        <div class="opt-upload">
          <form method="post" enctype="multipart/form-data">
            <input type="hidden" name="action" value="upload">
            <input type="file" name="upload" required><input type="submit" value="上传图片">
          </form>
        </div>
        <div class="opt-search">
          <form method="get" action="search.php">
            <input type="hidden" name="action" value="search">
            <input type="text" name="search" placeholder="输入关键词" required><input type="submit" value="搜索">
          </form>
        </div>
      </div>
      <div class="album">
        <?php if(empty($list['album']) && empty($list['picture'])): ?>
          <div class="album-tip">该相册为空。</div>
        <?php endif; ?>
        <!-- 子相册列表 -->
        <?php foreach ($list['album'] as $v): ?>
          <div class="album-list album-dir">
            <div class="album-list-content">
              <div class="album-list-tips">相册</div>
              <a href="?id=<?=$v['id']?>"><img src="./covers/<?=$v['cover'] ?: 'nopic.png'?>"></a>
              <div class="album-list-desc"><p><a href="?id=<?=$v['id']?>"><?=htmlspecialchars($v['name'])?></a> (<?=$v['total']?>)</p></div>
              <div class="album-list-opt">
                <form method="post">
                  <input type="hidden" name="action_id" value="<?=$v['id']?>">
                  <button class="js-del" name="action" value="delete">删除</button>
                </form>
              </div>
            </div>
          </div>  
        <?php endforeach; ?>
        <!-- 图片列表 -->
        <?php foreach($list['picture'] as $v): ?>
        <div class="album-list">
          <div class="album-list-content">
            <a href="show.php?id=<?=$v['id']?>"><img src="./thumbs/<?=$v['save']?>"></a>
            <div class="album-list-desc"><p><a href="show.php?id=<?=$v['id']?>"><?=htmlspecialchars($v['name'])?></a></p></div>
            <div class="album-list-opt">
              <form method="post">
                <input type="hidden" name="action_id" value="<?=$v['id']?>">
                <?php if($id): ?><button name="action" value="pic_cover">设为封面</button><?php endif; ?>
                <button class="js-del" name="action" value="pic_delete">删除</button>
              </form>
            </div>
          </div>
        </div>
        <?php endforeach; ?>
      </div>
    </div>
    <?php require './view/common/footer.html'; ?>
    <script src="./js/common.js"></script>
  </body>
</html>

后台关键逻辑代码:

<?php

/**
 * 查询相册记录(缓存查询结果)
 * @param int $id 相册ID
 * @return array 查询结果数组,不存在时返回false
 */
function album_data($id)
{
    static $data = [0 => false];
    if (!isset($data[$id])) {
        $data[$id] = db_fetch_row("SELECT `pid`,`path`,`name`,`cover`,`total` FROM `album` WHERE `id`=$id") ?: false;
    }
    return $data[$id];
}

/**
 * 查询相册层级导航
 * @param int $id 相册ID
 * @return array 查询结果数组,不存在时返回空数组
 */
function album_nav($id)
{
    $path = preg_replace('/^0,/', '', (album_data($id)['path'] . $id));
    return $path ? db_fetch_all("SELECT `id`,`name` FROM `album` WHERE `id` IN ($path) ORDER BY FIELD(`id`,$path)") : [];
}

/**
 * 查询当前相册所有的子相册和图片
 * @param int $id 相册ID
 * @param string $sort 排序(new、old)
 * @return array 查询结果数组
 */
function album_list($id, $sort)
{
    $sort = ($sort == 'old') ? 'ASC' : 'DESC';
    return [
        'album' => db_fetch_all("SELECT `id`,`name`,`cover`,`total` FROM `album` WHERE `pid`=$id  ORDER BY `id` $sort"),
        'picture' => db_fetch_all("SELECT `id`,`name`,`save` FROM `picture` WHERE `pid`=$id ORDER BY `id` $sort")
    ];
}

/**
 * 创建相册
 * @param int $pid 新相册的上级目录ID
 * @param string $name 新相册的名称
 */
function album_new($pid, $name)
{
    $data = album_data($pid);
    if (substr_count($data['path'], ',') >= config('LEVEL_MAX')) {
        return tips('无法继续创建子目录,已经达到最多层级!');
    }
 /* if (!preg_match('/^\w{1,12}$/', $name)) {
        return tips('无法创建相册,只允许1~12位字母、数字、下划线组成。');
    } */
    $name = mb_strimwidth(trim($name), 0, 12);
    db_exec('INSERT INTO `album` (`pid`,`path`,`name`) VALUES (?,?,?)', 'iss', [
        $pid, ($data['path'] . $pid . ','), ($name ?: '未命名')
    ]);
}

/**
 * 上传图片
 * @param int $pid 图片所属的相册ID
 * @param array $file 上传文件 $_FILES['xx'] 数组
 */
function album_upload($pid, $file)
{
    // 检查文件是否上传成功
    if (true !== ($error = upload_check($file))) {
        return tips("文件上传失败:$error");
    }
    // 检查文件类型是否正确
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    if (!in_array(strtolower($ext), config('ALLOW_EXT'))) {
        return tips('文件上传失败:只允许扩展名:' . implode(', ', config('ALLOW_EXT')));
    }
    // 生成文件名和保存路径
    $new_dir = date('Y-m/d');                       // 生成子目录
    $new_name = md5(microtime(true)) . ".$ext";     // 生成文件名
    // 创建原图保存目录
    $upload_dir = "./uploads/$new_dir";
    if (!is_dir($upload_dir) && !mkdir($upload_dir, 0777, true)) {
        return tips('文件上传失败:无法创建保存目录!');
    }
    // 创建缩略图保存目录
    $thumb_dir = "./thumbs/$new_dir";
    if (!is_dir($thumb_dir) && !mkdir($thumb_dir, 0777, true)) {
        return tips('文件上传失败:无法创建缩略图保存目录!');
    }
    // 保存上传文件
    if (!move_uploaded_file($file['tmp_name'], "$upload_dir/$new_name")) {
        return tips('文件上传失败:无法保存文件!');
    }
    // 创建缩略图
    thumb("$upload_dir/$new_name", "$thumb_dir/$new_name", config('THUMB_SIZE'));
    // 保存到数据库
    $name = mb_strimwidth(trim(pathinfo($file['name'], PATHINFO_FILENAME)), 0, 80);
    db_exec('INSERT INTO `picture` (`pid`,`name`,`save`) VALUES (?,?,?)', 'iss', [$pid, $name, "$new_dir/$new_name"]);
    $pid && album_total($pid, '+1');
}

/**
 * 修改相册的total字段
 * @param int $id 相册ID
 * @param string $method 操作(+1、-1)
 */
function album_total($id, $method = '+1')
{
    $path = preg_replace('/^0,/', '', (album_data($id)['path'] . $id));
    $path && db_exec("UPDATE `album` SET `total`=`total`$method WHERE `id` IN ($path)");
}

/**
 * 删除相册
 * @param int $id 相册ID
 */
function album_delete($id)
{
    $data = album_data($id);
    if ($data['total'] > 0) {
        return tips('删除失败:只能删除空相册!');
    }
    if (db_fetch_row("SELECT 1 FROM `album` WHERE `pid`=$id")) {
        return tips('删除失败:该相册含有子相册!');
    }
    db_exec("DELETE FROM `album` WHERE `id`=$id");
    $data['cover'] && is_file("./covers/{$data['cover']}") && unlink("./covers/{$data['cover']}");
}

/**
 * 查询图片记录
 * @param int $id 图片ID
 * @return array 查询结果数组,不存在时返回null
 */
function album_picture_data($id)
{
    return db_fetch_row("SELECT `pid`,`name`,`save` FROM `picture` WHERE `id`=$id");
}

/**
 * 设置图片为相册封面
 * @param int $id 图片ID
 * @param int $pid 相册ID
 */
function album_picture_cover($id, $pid)
{
    if (!$data = album_picture_data($id)) {
        return tips('设置失败:图片不存在!');
    }
    $cover_dir = './covers/' . dirname($data['save']);
    if (!is_dir($cover_dir) && !mkdir($cover_dir, 0777, true)) {
        return tips('设置失败:无法创建封面图保存目录!');
    }
    $cover_del = album_data($pid)['cover'];
    is_file("./covers/$cover_del") && unlink("./covers/$cover_del");
    copy("./thumbs/{$data['save']}", "./covers/{$data['save']}");
    db_exec("UPDATE `album` SET `cover`=? WHERE `id`=?", 'si', [$data['save'], $pid]);
    tips('设置成功!');
}

/**
 * 删除图片
 * @param int $id 图片ID
 */
function album_picture_delete($id)
{
    if (!$data = album_picture_data($id)) {
        return tips('删除失败:图片不存在!');
    }
    db_exec("DELETE FROM `picture` WHERE `id`=$id");
    is_file("./thumbs/{$data['save']}") && unlink("./thumbs/{$data['save']}");
    is_file("./uploads/{$data['save']}") && unlink("./uploads/{$data['save']}"); 
    $data['pid'] && album_total($data['pid'], '-1');
}

配套资源

PHP在线相册-强撸项目
https://download.csdn.net/download/dearmite/88084818

作业:

PHP在线相册,美化前台页面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/800942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode算法心得——合并后数组中的最大元素

大家好&#xff0c;我是晴天学长&#xff0c;这是一道动态规划的逆向思维题&#xff0c;此题甚是神奇&#xff01;&#x1f4aa;&#x1f4aa;&#x1f4aa; 1 &#xff09;合并后数组中的最大元素 2) .算法思路 只能选择旁边的&#xff0c;而且还是比自己等大或者比自己小的…

码银送书第四期《Python之光》

作为一种极其流行的编程语言&#xff0c;Python已经成为了当今最为重要的生产力工具之一。无论小学生还是各行各业的从业人员&#xff0c;都开始学习Python编程。这种编程语言在许多领域中都有广泛的应用&#xff0c;因此Python编程已经成为了许多职业的必备能力或者加分项。 …

【云边有个小卖部】上新《探秘Linux》第二章 Linux权限管理

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1C初阶C进阶数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我…

mac下安装vue cli脚手架并搭建一个简易项目

目录 1、确定本电脑下node和npm版本是否为项目所需版本。 2、下载vue脚手架 3、创建项目 1、下载node。 如果有node&#xff0c;打开终端&#xff0c;输入node -v和npm -v , 确保node和npm的版本&#xff0c;(这里可以根据自己的需求去选择&#xff0c;如果对最新版本的内容有…

JVM | 类加载是怎么工作的

类加载是怎么工作的 引言类加载器工作原理 | 城市建设过程1. 类加载器加载类前过程JVM进程启动 | 建筑工程立项Bootstrap类加载器创建扩展和应用类加载器 | 高级工程师的两位得力助手 2. 类加载器加载类后过程应用类加载器加载Building链接过程&#xff08;验证&#xff0c;准备…

Huge and Efficient! 一文了解大规模预训练模型高效训练技术

本文分为三部分介绍了大模型高效训练所需要的主要技术&#xff0c;并展示当前较为流行的训练加速库的统计。文章也同步发布在AI Box知乎专栏&#xff08;知乎搜索 AI Box专栏&#xff09;&#xff0c;欢迎大家在知乎专栏的文章下方评论留言&#xff0c;交流探讨&#xff01; 引…

计算机图形学十四路径追踪与渲染方程

路径追踪&#xff08;Path Tracing&#xff09;与渲染方程&#xff08;Render Equation&#xff09; 简介 利用路径追踪我们可以实现比whitted-style ray tracing更好的全局光照&#xff08;GI&#xff09;效果。它的理论基础是渲染方程&#xff0c;最开始由吉姆卡吉亚&#…

066、故障处理之热点问题

为什么要解决热点 分布式架构中各个组件的理想状态&#xff1a;资源利用率相对均衡 形成写热点的原因 高频访问的小表SQL执行计划不合理具有顺序增长属性的索引扫描 数据组织模型 例如数据是序列递增&#xff0c;则有可能数据全部都集中一个region上 &#xff0c;或者集中…

什么是等保定级?

TOC 一、等保评测介绍 1.1 等保定级目的 网络安全等级保护介绍&#xff1a;目的就是涉及民生问题的信息系统&#xff0c;要按照影响&#xff0c;提前划定等级 实施网络安全保护 信息系统&#xff1a;就是保护的系统&#xff0c;比如 魔幻的 健康码系统安全产品&#xff1a;健…

【lesson5】linux常见权限问题

文章目录 目录权限umask粘滞位 目录权限 先来思考一个问题: 进入一个目录需要什么权限呢&#xff1f; 由上图我们可以得知&#xff0c;进入目录需要x权限&#xff0c;那么没有r和w权限是什么情况呢&#xff1f; 从图中我们可以得知没有r权限不能查看目录里面的内容&#xff…

基于STM32设计的智能教室管理系统

前言 本文介绍了一个智慧教室的设计,该设计由电器设备控制系统、环境检测系统和考勤系统三大模块构成。通过使用STM32微处理器和物联网电器设备控制中心,实现对教室内风扇、照明灯和窗帘等电器设备的智能化统一控制与运行。同时,环境检测系统可以实时监测环境光强、温度、湿…

模型调参及优化

调参 调权重参数&#xff0c;偏置参数 训练数据集用来训练参数w&#xff0c;b 调超参数 验证数据集用来选择超参数学习率lr&#xff0c;隐藏层大小等 如何调参 当泛化误差和训练误差都没有降下去说明欠拟合&#xff1b;当训练误差降下去&#xff0c;但泛化误差出现上升形式&…

33. 本地记事本

本地记事本 html部分 <button class"add"><i class"iconfont icon-jiahao"></i> </button>css部分 *{margin: 0;padding: 0; } body{background-color: #7bdaf3;display: flex;padding-top: 3rem;flex-wrap: wrap; } .add{pos…

Vue2基础一、快速入门

零、文章目录 Vue2基础一、快速入门 1、Vue 概念 &#xff08;1&#xff09;为什么学 前端必备技能 岗位多&#xff0c;绝大互联网公司都在使用Vue 提高开发效率 高薪必备技能&#xff08;Vue2Vue3&#xff09; &#xff08;2&#xff09;Vue是什么 **概念&#xff1a;…

第二届“鼎信杯”榜单发布,麒麟信安荣获“优秀技术支撑奖”

由中国电子信息产业发展研究院、北京市海淀区人民政府主办&#xff0c;中国软件评测中心&#xff08;工业和信息化部软件与集成电路促进中心&#xff09;、中关村科学城管委会和北京市国际技术贸易协会承办的“2023 鼎信杯信息技术发展论坛”日前在北京举办。麒麟信安受邀参加主…

和鲸 ModelWhale 与麒麟系统适配认证,打造自主安全、性能可靠的信创 AI 基础软件

发展信创&#xff0c;解决核心技术的自主可控问题&#xff0c;是我国产业升级和数字经济发展过程中的重要命题。信创产业链主要由基础硬件、基础软件、应用软件、信息安全及云计算平台等几部分组成&#xff0c;拥抱信创国产化需要各厂商聚力共创生态&#xff0c;增强自身产品的…

JSONPath提取器案例详解

jsonpath语法 $ 表示根节点&#xff0c;也是所有jsonpath表达式的开始 . 表示获取子节点 .. 表示获取所有符合条件的内容 * 代表所有的元素节点 [] 表示迭代器的标示&#xff08;可以用于处理下标等情况&#xff09; [,] 表示多个结果的选择 ?() 表示过滤操作 表示当前节点一…

【QT】Day1

1. 收到实现登录框 要求&#xff1a; 1、登录窗口更改标题、图标 2、设置固定尺寸、并给定一定的透明度 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //信息调试类&#xff0c;用于打印输出的 #include <QIcon>…

windows命令行

参考:https://blog.csdn.net/u014419722/article/details/130427423 1、 创建文件夹&#xff08;mkdir或md&#xff09; 创建单个文件&#xff1a;mkdir cmd_test 创建二级文件&#xff1a;mkdir cmd_test\456\123 创建多个文件&#xff1a;mkdir cmd_test\000 cmd_test\111 2…

【js】javascript中base64转file、file压缩图片:

文章目录 一、效果图:二、实现代码: 一、效果图: 二、实现代码: /*** base64转file* param {string} urlData base64格式图片* returns */ export function base64ConvertFile(urlData) {if (typeof urlData ! string) {this.$toast("urlData不是字符串")return;}va…