许愿墙 --PHP

本文介绍了许愿墙项目,其功能包括查看、发表、修改和删除愿望,修改和删除需密码。给出了项目代码,涉及PHP函数编写、数据库连接与操作,还包含HTML页面布局。使用MySQL存储数据,实现了分页显示等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又是努力写代码的一天!!!

今写许愿墙

项目介绍 

在生活中,许愿墙是承载愿望的实体。最初人们将自己的愿望写在小纸片上,贴到墙上,形成了许愿墙。随着互联网的发展,在网站中实现发表愿望、展示愿望的功能,供人们表达自己的愿望并且浏览其他人的愿望,是网络形式的许愿墙。

       许愿墙的功能主要包括查看愿望、发表愿望、修改愿望和删除愿望,并且在修改和删除时需要输入密码,防止其他用户误删除别人的愿望。

项目代码

<?php

  /**

 * 接收输入的函数

  * @param array $method 输入的数组(可用字符串 get、post 来表示)

  * @param string $name 从数组中取出的变量名

  * @param string $type 表示类型的字符串

  * @param mixed $default 变量不存在时使用的默认值

  * @return mixed 返回的结果

  */

  function input($method, $name, $type = 's', $default = '')

  {

  switch ($method) {

  case 'get': $method = $_GET; break;

  case 'post': $method = $_POST; break;

 }

 $data = isset($method[$name]) ? $method[$name] : $default;

  switch ($type) {

  case 's':

    return is_string($data) ? $data : $default;

    case 'd':

    return (int)$data;

  case 'a':

  return is_array($data) ? $data : [];

  default:

  trigger_error('不存在的过滤类型“' . $type . '”');

  }

 }

   /**

   * 格式化日期

   * @param type $time 给定时间戳

   * @return string 从给定时间到现在经过了多长时间(天/小时/分钟/秒)

   */

   function format_date($time)

   {

   $diff = time() - $time;

   $format = [86400 => '天', 3600 => '小时', 60 => '分钟', 1 => '秒'];

   foreach ($format as $k => $v) {

   $result = floor($diff / $k);

   if ($result) {

   return $result . $v;

   }

   }

   return '0.5 秒';

   }  

    /**

  * 获取 LIMIT 的参数

  * @param int $page 当前页码值

  * @param int $size 每页显示的条数

  * @return string 生成后的结果

  */

  function page_sql($page, $size)

  {

  return ($page - 1) * $size . ',' . $size;

  }

   /**

  * 生成分页导航 HTML

  * @param string $url 链接地址

  * @param int $total 总记录数

  * @param init $page 当前页码值

  * @param int $size 每页显示的条数

  * @return string 生成的 HTML 结果

  */

  function page_html($url, $total, $page, $size)  

  {

  // 计算总页数

 $maxpage = max(ceil($total / $size), 1);

  // 如果不足 2 页,则不显示分页导航

  if ($maxpage <= 1) {

  return '';

  }

  if ($page == 1) {

  $first = '<span>首页</span>';

  $prev = '<span>上一页</span>';

  } else {

  $first = "<a href=\"{$url}1\">首页</a>";

  $prev = '<a href="' . $url . ($page - 1) . '">上一页</a>';

  }

  if ($page == $maxpage) {

  $next = '<span>下一页</span>';

  $last = '<span>尾页</span>';

  } else {

  $next = '<a href="' . $url . ($page + 1) . '">下一页</a>';

  $last = "<a href=\"{$url}{$maxpage}\">尾页</a>";

  }

  // 组合最终样式

  return "<p>当前位于:$page/$maxpage</p>$first $prev $next $last";

  }

<?php

 // 连接数据库

$link = mysqli_connect('localhost', 'root', '', 'php_wish');

if (!$link) {

    exit('数据库连接失败:' . mysqli_connect_error());

    }

 mysqli_set_charset($link, 'utf8');

// 设置 mbstring 扩展的内置编码

mb_internal_encoding('UTF-8');

?>

body{margin:0;background:#F7F7F7;}

.top{height:50px;border-bottom:1px solid #ebebeb;background:#fff;}

.top h1{margin:0;font-weight:400;font-size:1.8em;font-family:'Microsoft YaHei';line-height:50px;}

.top h1 a{color:#2FAE36;text-decoration:none;}

.container{margin:0 auto;width:80%;}

.note{margin-top:20px;padding:0 10px;padding-bottom:30px;border:1px solid #eee;background:#fff;color:#666;font-size:12px;font-family:arial,simsun;}

.note:after{clear:both;display:block;content:"";}

.note-top{margin:20px auto;margin-bottom:10px;text-align:center;}

.note-top-add{display:inline-block;padding:6px 18px;border-radius:2px;background-color:#6acd6a;color:#fff;cursor:pointer;transition:background-color .5s;}

.note-top-add:hover{background-color:#2FAE36;}

.note-top-add:active{background-color:#1F9E26;}

.note-box{display:flex;flex-wrap:wrap;justify-content:center;list-style-type: none;}

.note-list{position:relative;box-sizing:border-box;margin:10px;padding:10px;width:160px;height:175px;box-shadow:2px 2px 0 #DDD;}

.note-list-red{border:1px solid #FDC4F2;background-color:#FFD6F4;}

.note-list-blue{border:1px solid #A6E3FC;background-color:#C6F3FC;}

.note-list-yellow{border:1px solid #EDEB7C;background-color:#FFFCBC;}

.note-list-green{border:1px solid #A5F88B;background-color:#D5F8BB;}

.note-list:hover .note-list-action{display:block;}

.note-list-action{position:absolute;top:5px;right:8px;display:none;}

.note-list-edit{position:relative;top:-2px;float:left;margin-right:5px;color:#666;text-decoration:none;font-size:16px;}

.note-list-edit:hover{color:#EB1C27;}

.note-list-delete{float:left;color:#666;text-decoration:none;font-size:18px;}

.note-list-delete:hover{color:#EB1C27;}

.note-list-box{margin:0;margin-top:10px;padding:0;list-style:none;font-size:13px;line-height:20px;}

.note-list-name{margin-bottom:5px;padding-bottom:5px;border-bottom:1px dotted #fff;font-size:12px;}

.note-list-name span{font-weight:700;font-size:13px;}

.note-list-date{padding-top:5px;font-size:12px;}

.note-list-content{word-break:break-all;}

.note-layer{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;background-color:rgba(150,150,150,.2);align-items:center;justify-content:center;}

.note-edit{padding:15px;width:400px;border:10px solid rgba(106,205,106,.3);border-radius:5px;background-color:#fff;background-clip:padding-box;}

.note-edit-title{margin-bottom:8px;border:0;color:#299C30;font-weight:700;}

.note-edit-table{width:100%;border:0;border-collapse:collapse;}

.note-edit-table-w{width:210px;}

.note-edit-table td{padding-bottom:5px;}

.note-edit p{margin:0;margin-bottom:5px;}

.note-edit-content{box-sizing:border-box;margin-bottom:5px;padding:3px;width:100%;height:80px;border:1px solid #ccc;color:#666;font-size:12px;font-family:arial,simsun;}

.note-edit-pwd{padding:3px;width:115px;border:1px solid #ccc;color:#666;font-size:12px;font-family:arial,simsun;}

.note-edit-name{padding:3px;width:180px;border:1px solid #ccc;color:#666;font-size:12px;font-family:arial,simsun;}

.note-edit-submit{padding:4px 10px;border:1px solid #2cb82c;border-radius:2px;background-color:#6acd6a;color:#fff;letter-spacing:2px;font-size:12px;cursor:pointer;transition:background-color .5s;}

.note-edit-submit:hover{background-color:#2FAE36;}

.note-edit-submit:active{background-color:#1F9E26;}

.note-edit-cancel{margin-left:5px;padding:4px 10px;border:1px solid #2cb82c;border-radius:2px;background-color:#6acd6a;color:#fff;letter-spacing:2px;font-size:12px;cursor:pointer;transition:background-color .5s;}

.note-edit-cancel:hover{background-color:#2FAE36;}

.note-edit-cancel:active{background-color:#1F9E26;}

.note-edit-red input{display:none;}

.note-edit-red{display:inline-block;width:20px;height:20px;border:1px solid #FDB4E2;background-color:#FDC4F2;cursor:pointer;}

.note-edit-red:hover{border:1px solid #CD74A2;}

.note-edit-red-curr{border:1px solid #CD74A2;}

.note-edit-blue input{display:none;}

.note-edit-blue{display:inline-block;width:20px;height:20px;border:1px solid #A6E3FC;background-color:#A6E3FC;cursor:pointer;}

.note-edit-blue:hover{border:1px solid #55A5B7;}

.note-edit-blue-curr{border:1px solid #55A5B7;}

.note-edit-yellow input{display:none;}

.note-edit-yellow{display:inline-block;width:20px;height:20px;border:1px solid #FDFB8C;background-color:#FDFB8C;cursor:pointer;}

.note-edit-yellow:hover{border:1px solid #BEBC45;}

.note-edit-yellow-curr{border:1px solid #BEBC45;}

.note-edit-green input{display:none;}

.note-edit-green{display:inline-block;width:20px;height:20px;border:1px solid #A5F88B;background-color:#A5F88B;cursor:pointer;}

.note-edit-green:hover{border:1px solid #78C755;}

.note-edit-green-curr{border:1px solid #78C755;}

.note-page{overflow:hidden;text-align:center;line-height:14px;}

.note-page a{display:inline-block;margin:0 3px;padding:2px 12px;height:24px;border:1px solid #ccc;background:#fff;color:grey;text-decoration:none;font-size:12px;line-height:24px;transition:all .2s;}

.note-page a:hover{border:1px solid #2FAE36;color:#2FAE36;}

.note-page span{display:inline-block;margin:0 3px;padding:2px 12px;border:1px solid #ccc;background:#fcfcfc;color:#bbb;font-size:12px;line-height:24px;}

.note-page p{margin:1em 0;}

/* 设置单选框选中效果 */

(function(){

    var curr = function(target){

        var label = ["red", "green", "yellow", "blue"], obj = [], v;

        for(v in label){

            obj[v] = target.find(".note-edit-" + label[v]);

            obj[v].find("input:checked").length && obj[v].addClass("note-edit-" + label[v] + "-curr");

            obj[v].click(function(){

                for(v in obj){

                   var curr = "note-edit-" + label[v] + "-curr";

                   obj[v].find("input:checked").length ? obj[v].addClass(curr) : obj[v].removeClass(curr);

                }

            });

        }

    };

    curr($(".js-note-add"));

    curr($(".js-note-edit"));

})();

/* 添加按钮 */

$(".note-top-add").click(function(){

    $(".js-note-add").fadeIn(200);

});

/* 取消按钮 */

$(".note-edit-cancel").click(function(){

    $(this).parents(".note-layer").fadeOut(200);

});

/* 删除按钮 */

$(".note-list-delete").click(function(){

    return confirm('您确定要删除吗?');

});

<div class="note-layer js-note-add" style="display:none">

  <div class="note-edit">

    <div class="note-edit-title">我要许愿</div>

    <form method="post" action="./save.php">

      <table class="note-edit-table">

        <tr>

          <td class="note-edit-table-w">

            <p>我的名字:</p>

            <input class="note-edit-name" type="text" name="name" placeholder="匿名">

          </td>

          <td>

            <p>贴纸颜色:</p>

            <label class="note-edit-green"><input type="radio" name="color" value="green" checked></label>

            <label class="note-edit-blue"><input type="radio" name="color" value="blue"></label>

            <label class="note-edit-yellow"><input type="radio" name="color" value="yellow"></label>

            <label class="note-edit-red"><input type="radio" name="color" value="red"></label>

          </td>

        </tr>

        <tr>

          <td colspan="2">

            <p>我的愿望:</p>

            <textarea class="note-edit-content" name="content" placeholder="80个字符以内(中文占2个字符位)"></textarea>

          </td>

        </tr>

        <tr>

          <td>

            保护密码:

            <input class="note-edit-pwd" type="password" name="password" placeholder="6个字符以内">

          </td>

          <td>

            <input class="note-edit-submit" type="submit" value="提交">

            <input class="note-edit-cancel" type="button" value="取消">

          </td>

        </tr>

      </table>

    </form>

  </div>

</div>

<div class="note-layer js-note-edit">

  <div class="note-edit">

    <div class="note-edit-title">编辑愿望</div>

    <form method="post" action="./save.php?id=<?=$id?>&page=<?=$page?>">

      <table class="note-edit-table">

        <tr>

          <td class="note-edit-table-w">

            <p>我的名字:</p>

            <input class="note-edit-name" type="text" name="name" placeholder="匿名" value="<?=htmlspecialchars($edit['name'])?>">

          </td>

          <td>

            <p>贴纸颜色:</p>

            <label class="note-edit-green"><input type="radio" name="color" value="green" <?=$edit['color']=='green' ? 'checked' : ''?>></label>

            <label class="note-edit-blue"><input type="radio" name="color" value="blue" <?=$edit['color']=='blue' ? 'checked' : ''?>></label>

            <label class="note-edit-yellow"><input type="radio" name="color" value="yellow" <?=$edit['color']=='yellow' ? 'checked' : ''?>></label>

            <label class="note-edit-red"><input type="radio" name="color" value="red" <?=$edit['color']=='red' ? 'checked' : ''?>></label>

          </td>

        </tr>

        <tr>

          <td colspan="2">

            <p>我的愿望:</p>

            <textarea class="note-edit-content" name="content"><?=htmlspecialchars($edit['content'])?></textarea>

          </td>

        </tr>

        <tr>

          <td></td>

          <td>

            <input type="hidden" name="password" value="<?=htmlspecialchars($password)?>">

            <input class="note-edit-submit" type="submit" value="提交">

            <input class="note-edit-cancel" type="button" value="取消">

          </td>

        </tr>

      </table>

    </form>

  </div>

</div>

<div class="note-layer">

  <div class="note-edit">

    <div class="note-edit-title">验证密码</div>

    <form method="post">

      <table class="note-edit-table">

        <?php if(isset($tips)): ?>

        <tr>

          <td colspan="2"><?=$tips?></td>

        </tr>

        <?php endif; ?>

        <tr>

          <td class="note-edit-table-w">

            输入密码:

            <input class="note-edit-pwd" type="password" name="password" placeholder="6个字符以内">

          </td>

          <td>

            <input class="note-edit-submit" type="submit" value="验证">

            <input class="note-edit-cancel" type="button" value="取消">

          </td>

        </tr>

      </table>

    </form>

  </div>

</div>

<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8">

    <title>许愿墙</title>

    <link rel=stylesheet href="./css/style.css">

  </head>

  <body>

    <div class="top">

      <div class="container"><h1><a href="index.php">许愿墙</a></h1></div>

    </div>

    <div class="container note">

      <div class="note-top"><div class="note-top-add">我要许愿</div></div>

      <div class="note-box">

        <!-- 输出许愿墙 -->

        <?php foreach($data as $v): ?>

          <div class="note-list note-list-<?=$v['color']?>">

            <div class="note-list-action">

              <a class="note-list-edit" href="./index.php?action=edit&id=<?=$v['id']?>&page=<?=$page?>" title="修改">✎</a>

              <a class="note-list-delete" href="./index.php?action=delete&id=<?=$v['id']?>&page=<?=$page?>" title="删除">×</a>

            </div>

            <ul class="note-list-box">

              <li class="note-list-name">FROM: <span><?=htmlspecialchars($v['name'])?></span></li>

              <li class="note-list-content"><?=htmlspecialchars($v['content'])?></li>

              <li class="note-list-date">(<?=format_date($v['time'])?>前 <?=date('H:i', $v['time'])?>)</li>

            </ul>

          </div>

        <?php endforeach; ?>

      </div>

      <!-- 添加愿望表单 -->

       <?php require './view/common/add.html'; ?>

      <!-- 编辑愿望表单 -->

      <?php if ($id): require './view/common/password.html'; endif; ?>

      <?php if ($id):

          require './view/common/' . ($checked ? 'edit' : 'password') . '.html';

        endif; ?>

      <!-- 分页链接 -->

      <div class="note-page">

        <?=page_html('./index.php?page=', $total, $page, $size)?>

      </div>

    </div>

    <script src="./js/jquery-1.12.4.min.js"></script>

    <script src="./js/common.js"></script>

  </body>

</html>

<?php

require './common/init.php';

require './common/function.php';

// 获取当前页码,限制最小值为 1

$page = max(input('get', 'page', 'd'), 1);

$size = 4; // 每页显示的条数

$sql = 'SELECT count(*) FROM `wish`';

if (!$res = mysqli_query($link, $sql)) {

    exit("SQL[$sql]执行失败:" . mysqli_error($link));

}

$total = (int)mysqli_fetch_row($res)[0];

// 分页查询愿望

$sql = 'SELECT `id`,`name`,`content`,`time`,`color` FROM `wish`

        ORDER BY `id` DESC LIMIT ' . page_sql($page, $size);

if (!$res = mysqli_query($link, $sql)) {

    exit("SQL[$sql]执行失败:" . mysqli_error($link));

    // 查询结果为空时,自动返回第 1 页

    if (empty($data) && $page > 1) {

        header('Location: index.php?page=1');

        exit;

    }

}

// 获取待编辑的愿望 id

$id = max(input('get', 'id', 'd'), 0);

if ($id) {

    // 根据 id 查询出愿望信息

    $password = input('post', 'password', 's');

    $sql = 'SELECT `name`,`content`,`color`,`password` FROM `wish`

     WHERE `id`=' . $id;

    if (!$res = mysqli_query($link, $sql)) {

        exit("SQL[$sql]执行失败:" . mysqli_error($link) . $sql);

    }

    if (!$edit = mysqli_fetch_assoc($res)) {

        exit('该愿望不存在!');

    }

    mysqli_free_result($res);

    // 验证密码是否正确

    $checked = isset($_POST['password']) || empty($edit['password']);

    if ($checked && $password !== $edit['password']) {

        $tips = '密码不正确!';

        $checked = false;

    }

    if ($checked && $action == 'delete') {

        $sql = 'DELETE FROM `wish` WHERE `id`=' . $id;

        if (!mysqli_query($link, $sql)) {

            exit('SQL 执行失败:' . mysqli_error($link));

        }

        header('Location: index.php');

        exit;

    }

}

$data = mysqli_fetch_all($res, MYSQLI_ASSOC);

mysqli_free_result($res);

mysqli_close($link);

require './view/index.html';

<?php

require './common/init.php';

require './common/function.php';

// 接收变量

 $name = trim(input('post', 'name', 's'));

 $color = input('post', 'color', 's');

 $content = trim(input('post', 'content', 's'));

 $password = input('post', 'password', 's');

 // 限制名称最多占用 12 个字符位置(1 个汉字占用 2 个位置)

 $name = mb_strimwidth($name, 0, 12);

  // 当名称为空时,使用“匿名”作为默认值

  $name = $name ?: '匿名';

  // 限制颜色值在合法范围内,使用“green”作为默认值

  if (!in_array($color, ['blue', 'yellow', 'green', 'red'])) {

            $color = 'green';

 }

  // 限制内容长度最多占用 80 个字符位置

  $content = mb_strimwidth($content, 0, 80);

  // 限制密码长度最多为 6 位

  $password = (string)substr($password, 0, 6);

  // 保存用户的发布时间

  $time = time();

// 接收待修改的愿望 id

 $id = max(input('get', 'id', 'd'), 0);

 if ($id) {

 // 验证密码是否正确

 $sql = 'SELECT `password` FROM `wish` WHERE `id`=' . $id;

    if (!$res = mysqli_query($link, $sql)) {



 

       

       exit("SQL[$sql]执行失败:" . mysqli_error($link));

    }

    if (!$data = mysqli_fetch_assoc($res)) {

    exit('该愿望不存在!');

 }

     if ($data['password'] !== $password) {

    exit('密码不正确!');

 }

 // 保存到数据库

 $sql = 'UPDATE `wish` SET `name`=?,`color`=?,`content`=? WHERE `id`=?';

 if (!$stmt = mysqli_prepare($link, $sql)) {

 exit("SQL[$sql]预处理失败:" . mysqli_error($link));

 }

 mysqli_stmt_bind_param($stmt, 'sssi', $name, $color, $content, $id);

  if (!mysqli_stmt_execute($stmt)) {

  exit('数据库操作失败:' . mysqli_stmt_error($stmt));

  }

  // 执行完成,跳转回许愿墙,并传递页码值

  $page = max(input('get', 'page', 'd'), 1);

  header("Location: index.php?page=$page");

  exit;

  }

  $sql = 'INSERT INTO `wish` (`name`,`color`,`content`,`password`,`time`)

  VALUES (?,?,?,?,?)';

  if (!$stmt = mysqli_prepare($link, $sql)) {

  exit("SQL[$sql]预处理失败:" . mysqli_error($link));

  }

  mysqli_stmt_bind_param($stmt, 'ssssi', $name, $color, $content, $password, $time);

  if (!mysqli_stmt_execute($stmt)) {

  exit('数据库操作失败:' . mysqli_stmt_error($stmt));

  }

 header('Location: index.php');

项目数据库

运行截图

小新码农,不足点请多多包含,也欢迎大家一起探讨哦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值