阿里百秀实战项目

  • 项目预览演示

一个自媒体信息发布平台

管理员(编辑)通过网站后台管理界面管理(发布、维护)自媒体内容

 

用户可以通过网站前台查看内容

准备工作

  • 数据库设计
  • 基础结构搭建

数据库设计

根据我们的业务需要设计数据库的结构,这个过程是每个项目开始时所必须的,一般由专门的 DBA 角色完成(很多没有划分的非常具体的公司由后端开发人员兼任)。

 

搭建项目架构

项目最基本的分为两个大块,前台(对大众开放)和后台(仅对管理员开放)。

第一步:搭建基本结构目录

└── baixiu ······································ 项目文件夹(网站根目录)
    ├── admin ··································· 后台文件夹
    │   └── index.php ··························· 后台脚本文件
    ├── static ·································· 静态文件夹
    │   ├── assets ······························ 资源文件夹
    │   └── uploads ····························· 上传文件夹
    └── index.php ······························· 前台脚本文件

基本原则:

  • 先明确一共有多少个页面
  • 一个页面就对应一个php文件去处理

第二步:整合静态资源文件

静态文件VS动态文件

  • 静态文件指的就是服务器不会经过任何处理就返回客户端的文件,比如:图片、样式表、字体文件等
  • 动态文件指的就是服务器会对请求的文件进行处理,并将处理后的结果返回给客户端的文件,比如:PHP文件、ASP文件等

具体操作

└── baixiu ······································ 项目文件夹(网站根目录)
    ├── ......
    ├── static ·································· 静态文件夹
    │   ├── assets ······························ 资源文件夹
+   │   │   ├── css ····························· 样式文件夹
+   │   │   ├── img ····························· 图片文件夹
+   │   │   ├── js ······························ 脚本文件夹
+   │   │   └── venders ························· 第三方资源
    │   └── uploads ····························· 上传文件夹
+   │       └── 2017 ···························· 2017 年上传文件目录
    ├── ......

注意:

  • static 目录中只允许出现静态文件
  • assets目录中放置网页中所需的的资源文件
  • uploads目录中放置网站运营过程中上传的文件,如果担心文件过多,可以按年归档(一年一个文件夹)

第三步:配置项目文件

由于在接下来的开发过程中,肯定有一部分公共的成员,例如数据库主机、数据库用户名、数据库密码等,这些数据应该放到公共的地方,抽象成一个配置文件config.php放到项目根目录下。

这个配置文件采用定义常量的方式定义配置成员:

<?php

/**
 * 我们项目中用到的配置信息
 */



/**
 * 数据库用主机
 */
define('DB_HOST', 'localhost');
/**
 * 数据库用户名
 */

define('DB_USER', 'root');
/**
 * 数据库密码
 */

define('DB_PASS', '123');
/**
 * 数据库名字
 */

define('DB_NAME', 'baixiu');

 

注意:这种只有服务端的PHP文件应该去除结尾处的?>,防止输出内容

在需要配置文件的时间可以通过require载入:

<?php 
//载入配置文件
require_once '../config.php';

 

项目架构总结

架构的目的就是搭建一个基本的架子或者说是制定一个基础的约束,让所有的开发人员基于这一个约束基础之上展开开发工作

有利于后期维护(不至于写一段时间过后大家都不认识这个项目,找一个文件,找一个功能找半天)

 

开始编码

对于网站功能开发人员来说,他们在展开工作之前就已经完成了静态页面的制作,接下来就是具体开发每一个业务功能。

下面有一种方式:

先把每一个静态页直接转成一个对应的PHP文件,调整页面中的资源路径,然后在此静态页面可以访问的基础之上实现各个功能

第四步:整合全部静态页面

1、将静态页面全部拷贝到admin目录中

2、将文件扩展名由.html改为.php,页面中的a链接也需要调整

3、调整页面中的静态资源路径,将原本的相对路径调整为绝对路径

绝对路径vs相对路径

  1. 不会跟随当前页面的访问地址的变化而变化
  2. 更简洁明了,不容易出错,不用一层一层的找

第五步:抽离公共部分
 

由于每一个页面中都有一部分代码(侧边栏)是相同的,分散到各个文件中,不容易维护,所有应该抽象到一个公共的文件中。

于是我们在admin目录中创建一个inc子目录,在这个目录中创建一个sidebar.php文件,用于抽象公共的侧边栏

<div class="aside"> ... </div>

,然后在每一个需要的模块的页面中通过include载入:

...
<?php include 'inc/sidebar.php' ;?>
...

第六步:侧边栏的焦点状态

由于侧边栏在不同页面时,active class name出现的位置不尽相同,所以我们需要区别当前sidebar.php文件是在哪个页面中载入的,从而明确焦点状态。

所以目前的关键问题就出现在了如何在 sidebar.php 中知道当前被哪个文件载入了。

通过查看 include 函数的文档发现:如果 a.php 通过 include 载入了 b.php 文件,那么在 b.php 文件中可以访问到 a.php 中定义的变量。

http://php.net/manual/zh/function.include.php

借助这个特性,我们可以在各个页面中定义一个标识变量,然后在 sidebar.php 中通过这个标识变量区别不同页面的载入:

每一个菜单项 <li> 元素:

...
<li <?php echo $current_page == 'comments' ? 'class="active"':''; ?>>
        <a href="/admin/comments.php"><i class="fa fa-comments"></i>评论</a>
</li>
...

 

对于有子菜单的菜单项,有一点例外:

...
<?php $menu_posts = array('posts','post-add','categories'); ?>
<li <?php echo in_array($current_page, $menu_posts) ? 'class="active"':''; ?>>
        <a href="#menu-posts" <?php echo in_array($current_page, $menu_posts) ? '':'class="collapsed"'; ?> data-toggle="collapse">
          <i class="fa fa-thumb-tack"></i>文章<i class="fa fa-angle-right"></i>
        </a>
        <ul id="menu-posts" class="collapse<?php echo in_array($current_page, $menu_posts) ? ' in':''; ?>">
          <li <?php echo $current_page == 'posts' ? 'class="active"':''; ?>><a href="/admin/posts.php">所有文章</a></li>
          <li <?php echo $current_page == 'post-add' ? 'class="active"':''; ?>><a href="/admin/post-add.php">写文章</a></li>
          <li <?php echo $current_page == 'categories' ? 'class="active"':''; ?>><a href="/admin/categories.php">分类目录</a></li>
        </ul>
</li>
...

 

管理后台登录

第七步:处理 HTML 中需要调整的地方

在写静态页面时,我们一般不会关心功能实现过程中对 HTML 的要求,特别是表单一类的 HTML,在实际开发功能时我们一般都会使用到表单的 action 和 method 属性,还有表单元素的 name 属性等等。

这里我们需要调整的有:

  1. 给form表单添加action和method属性
  2. 给邮箱和密码添加name属性
  3. 将登陆按钮由a链接改为button提交按钮

登陆业务逻辑

用户第一次访问登录页面(GET),服务端会返回(响应)一个包含登录表单的 HTML 给浏览器。

当用户填写完表单点击登录按钮,浏览器会再发送一个 POST 请求到 login.php 文件

 

第八步:判断是否以POST方法请求

在 PHP 脚本开始执行时,判断当前请求是否是以 POST 方式提交:

<?php
// 判断当前是否是 POST 请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // TODO: 是 POST 提交
}
...

参数处理:如果是 POST 提交,则通过 $_POST 关联数组获取用户在表单中填写的邮箱和密码。

合法化校验:如果邮箱或者密码没有填写的话,应该提示用户完整填写邮箱和密码,并结束之后的逻辑(没必要执行了)。

//1.接收并校验
  if (empty($_POST['email'])) {
    $GLOBALS['message'] = '请输入邮箱';
    return;
  }
   if (empty($_POST['password'])) {
    $GLOBALS['message'] = '请输入密码';
    return;
  }

错误信息展示:如果执行逻辑过程中出现错误,界面上必须要有一个错误信息的展示,我们的方案就是在出错过后,定义一个错误信息的变量,最后在渲染 HTML 时输出到 HTML 中:

 <!-- 有错误信息时展示 -->
      <?php if (isset($message)): ?>
        <div class="alert alert-danger">
        <strong>错误!</strong> <?php echo $message ?>
      </div>
      <?php endif ?>

接收参数:

 $email = $_POST['email'];
 $password = $_POST['password'];

 

第九步:表单状态保持

当用户填写错误的邮箱或密码提交过后,再次得到 HTML 页面显示时,除了可以看见错误信息,应该也可以看到之前填写邮箱(非敏感数据)

解决办法也很简单:在输出 <input> 时为其添加一个 value 属性

<input id="email" name="email" type="email" class="form-control" placeholder="邮箱" autofocus value="<?php echo empty($_POST['email'])? '':$_POST['email'] ?>">

 

第十步:数据库连接查询

 

只有数据库才“知道”邮箱与密码是否正确,所以必须通过查询数据库验证邮箱和密码。

根据邮箱查询用户:根据邮箱到数据库中查询对应的用户,如果查询不到则代表用户不存在

$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
  if (!$conn) {
    exit('<h1>连接数据库失败</h1>');
  }
    $query = mysqli_query($conn,"select * from users where email = '{$email}' limit 1 ;");
    if (!$query) {
      $GLOBALS['message'] = '登录失败,请重试';
      return;
    }
    //获取登录用户
    $users = mysqli_fetch_assoc($query);
    if (!$users) {
      //用户名不存在
      $GLOBALS['message'] = '密码与邮箱不匹配';
      return;
    }

用户密码比对:比对用户密码是否与表单提交过来的相同

 if ($users['password'] !== $password) {
      //密码错误
      $GLOBALS['message'] = '密码与邮箱不匹配';
      return;
    }

 

第十一步:访问控制及登陆状态保持

至此,我们已经完成了登录校验的功能,但是如果我们记住登陆后(约定如此)才可以访问的页面地址,直接在地址栏输入,则可以越过登陆页面的限制直接访问。这样的话登录页形同虚设,没有任何价值。

解决方法:在需要访问权控制页面加上访问控制(硬性控制),具体方法就是根据用户之前的登录状态来决定是否可以访问,如果没有登录就不让其访问。

Session 这种机制会更加适合于做登录状态保持,因为客户端不再保存具体的数据,只是保存一把“钥匙”,伪造一把可以用的钥匙,可能性是极低的,所以不需要在意。

session_start();
if (empty($_SESSION['login_user'])) {
  //如果没有当前用户信息,意味着没有登录过
  header('Location:/admin/login.php');
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3876057/blog/1831561

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值