美文网首页
php学习路(八) --Tp项目web工程总结

php学习路(八) --Tp项目web工程总结

作者: 爱编程的凯哥 | 来源:发表于2019-01-05 22:10 被阅读14次

这一章,我们总结下项目中遇到的问题,以便以后使用:

问题目录:

  1. php中类似拦截器的功能实现权限管理
  2. 项目中的静态资源管理
  3. 自定义目录类的加载
  4. 异常类的定义
  5. html页面对应php对象取值
  6. html页面对应php的if、foreach写法
  7. php中ajax用法
  8. php分页写法
  9. 常量定义
  10. checkbox用jq全选二次操作失效
  11. session管理
  12. 模型类定义

内容:

  1. php中类似拦截器的功能实现权限管理
    权限功能在任何工程都是必不可少,demo实现了简单的登录验证,用户的权限管理未实现,可以参考思路。
  • 首先定义PermissionController,作为顶层controller,除了登录controller以外所有controller都是其子类。
namespace Base\Controller;


use Think\Controller;

class PermissionController extends Controller
{
  //实现_initialize方法,所有子类的的初始化时调用父类的的_initialize方法进行验证
    public function _initialize(){
        $loginVo=session('loginVo');
        if(empty($loginVo)){
            $this->redirect("/Home/Index");
        }else{
            $this->assign('loginVo',$loginVo);
        }
    }
}
  • 定义BaseController,做为PermissionController的子类,其他controller的直接父类,实现了公用方法,分页页将会封装到此类中
namespace Home\Controller;

use Think\Page;
use Base\Controller\PermissionController;

class BaseController extends PermissionController
{
    //基础实现,直接调用父类的初始化验证权限
    public function _initialize(){
       parent::_initialize();
    }

    /**
     * 基础分页的相同代码封装,使前台的代码更少
     * @param $count 要分页的总记录数
     * @param int $pagesize 每页查询条数
     * @return \Think\Page
     */
    public function getpage($count, $pagesize = 10) {
        $p = new Page($count, $pagesize);
        $p->setConfig('header', '<li class="rows">共<b>%TOTAL_ROW%</b>条记录&nbsp;第<b>%NOW_PAGE%</b>页/共<b>%TOTAL_PAGE%</b>页</li>');
        $p->setConfig('prev', '上一页');
        $p->setConfig('next', '下一页');
        $p->setConfig('last', '末页');
        $p->setConfig('first', '首页');
        $p->setConfig('theme', '%FIRST%%UP_PAGE%%LINK_PAGE%%DOWN_PAGE%%END%%HEADER%');
        $p->lastSuffix = false;//最后一页不显示为总页数
        return $p;
    }
}

具体类使用

amespace User\Controller;


use Home\Controller\BaseController;
use mysql_xdevapi\Exception;
use Think\Log;

class AdminController extends BaseController
{
//通过父类管理权限,和分页基本方法
.......
}

综上,采用继承到写法实现了类似于拦截器到逻辑来管理用户权限和一些基本公用操作。

  1. 项目中的静态资源管理
  • 首先根目录下有个Public目录(没有新建),在Application/Common/Conf/config.php中配置静态资源路径
    'TMPL_PARSE_STRING' => array(
        '/Public' =>  .'/Public',
        '__JS__' =>  .'/Public/Js',
        '__CSS__' =>  .'/Public/Css',
        '_IMAGE' =>  .'/Public/Images',
    ),

  • 页面使用
    <script src="__JS__/jquery.min.js"></script>
    <link href="__CSS__/query_style.css" rel="stylesheet" type="text/css">

  1. 自定义目录类的加载
  • 自己定义顶层目录,tp是不会自动加载到,比如我们的工具类,异常类啥的,需要在Application/Common/Conf/config.php中配置
    'AUTOLOAD_NAMESPACE' => array(
        'Utils' => APP_PATH.'Utils', //自定义加载的路径
        "Error" => APP_PATH.'Exception',
        "Model" => APP_PATH.'Model',
        "Interceptor" => APP_PATH.'Inteceptor'
    ),

  • 类中引用
use Model\LoginModel;
use Think\Controller;
use Utils\LoginUtils;

如果不定义此配置,会报错找不到类

  1. 异常类的定义
  • 异常类可以继承\ThinkPhp中Excpetion的方式自定义一次异常,然后通过try-catch进行处理
  • demo中采用了类似api处理异常dto的方法,返回异常模型类

class LoginUtils
{
    public static function checkLogin($loginName,$password){
        $model=M("users u");
        $map=array();
        $map['name']=$loginName;
        $result=$model->field("u.name,u.deploy_name,p.pass")->join("left join password p on  u.id=p.user_id")
            ->where($map)->order('u.Create_time desc')->limit(2)->select();
        if(empty($result)){
            $noUserException = new NoUserException("用户不存在");
            return $noUserException;
        }else if($result[0]["pass"]!=$password){
            return new ErrorPassowrdException("密码错误!");
        }else {
            return new LoginModel($loginName,$password,$result[0]['deploy_name']);
        }
    }
}
  • 工具类返回数据后,进行类型判断
 if(empty($checkFailMsg)){
            $checkLogin=new LoginUtils();

            $result= LoginUtils::checkLogin($loginName,$password);
            if(!$result instanceof LoginModel){
                $checkFailMsg=$result->getMsg();
            }

        }

注意: $result= LoginUtils::checkLogin($loginName,$password);中::为php中静态方法引用的方法。

  1. html页面对应php对象取值

    • 页面或取php对象的值,采用嵌入php的写法
      您好! <?php echo $loginVo->getDeployName();?> ,欢迎您登录管理中心</span><a href="#" class="help">帮助</a>
      这种方式,简单的调用了php对象的属性和方法。
  2. html页面对应php的if、foreach写法
    和5类似,有一样的写法,也有if和foreach的模版标签支持

      //if标签
              <if condition="$list neq null">
      //for标签
                   <foreach name="list" item="l">
                       <tr>
                           <td><input type="checkbox" data-id="{$l.id}" name="userBox"/></td>
                           <td>{$l.id}</td>
                           <td>{$l.name}</td>
                           <td>{$l.deploy_name}</td>
                           <td>{$l.mail}</td>
                           <if condition="$l.sex eq 0">
                               <td>未知</td>
                           </if>
                           <if condition="$l.sex eq 2">
                               <td>女</td>
                           </if>
                           <if condition="$l.sex eq 1">
                               <td>男</td>
                           </if>
                           <td>{$l.create_time}</td>
        //利用php的if,处理复杂的判断,支持if,esleif,else等等
                           <?php if ($l.status == 'ACTIVE'): ?>
                                <td>已激活</td>
                           <?php else : ?>
                                <td>已冻结</td>
                           <?php endif?>

                           <td><scan style="color: #2433ff;"  data-id="{$l.id}" onclick="updateUser(this)">更新</scan></td>
                       </tr>
                   </foreach>
                </if>
  1. php中ajax用法
    *前段页面和其他web项目一样

    function del() {
        var checkedBox=$("input[name='userBox']:checked");
        if(checkedBox.length==0){
            alert("最少选择一个删除用户!");
            return false;
        }else{
            var ids=new Array();
            for(var i=0;i < checkedBox.length;i++){
                ids[i]=$(checkedBox[i]).attr("data-id");
            }

            $.ajax({
                type: "POST",
                url: "/User/Admin/doDelUser",
                data: {"ids":ids},
                success: function(result){
                    alert(result.message);
                    if(result.status=='success'){
                        window.location.href="/User/Admin/query";
                    }

                },

                error(e){
                    console.log(e);
                    alert("系统异常!");
                },


            });

        }



    }
  • 后段通过ajaxReturn返回结果对象
  .......
       $model->where("id=" . $id)->save($map);
            $result['status']="success";
            $result['name']=$user[0]['name'];

            $result['message']="修改成功!";
        } catch (\Exception $e) {
            $result['status']="fail";
            $result['message']=$e->getMessage();
        }
        $this->ajaxReturn($result);

  1. php分页写法

thintkphp支持分页,实现起来比较简单

  • 首先我在父类BaseController定义了公用方法
    public function getpage($count, $pagesize = 10) {
        $p = new Page($count, $pagesize);
        $p->setConfig('header', '<li class="rows">共<b>%TOTAL_ROW%</b>条记录&nbsp;第<b>%NOW_PAGE%</b>页/共<b>%TOTAL_PAGE%</b>页</li>');
        $p->setConfig('prev', '上一页');
        $p->setConfig('next', '下一页');
        $p->setConfig('last', '末页');
        $p->setConfig('first', '首页');
        $p->setConfig('theme', '%FIRST%%UP_PAGE%%LINK_PAGE%%DOWN_PAGE%%END%%HEADER%');
        $p->lastSuffix = false;//最后一页不显示为总页数
        return $p;
    }
  • 业务controller中调用父类方法,定义分页条件
      //查询总数
        $count = $model->where($map)->count();
    // 调用父类方法初始化页面参数
        $p = parent::getpage($count,C('PAGE_SIZE'));
    //查询sql拼接imit($p->firstRow, $p->listRows)条件
        $result=$model->field("id,name,deploy_name,sex,CREATE_TIME,mail,status")->where($map)->order('id desc ')
            ->limit($p->firstRow, $p->listRows)->select();
  1. 常量定义

    常量的使用必不可少,做法是在Application/Common/Conf目录定义常量文件cons1.php

<?php
/**
 * Created by PhpStorm.
 * User: kai.yang
 * Date: 2019-01-05
 * Time: 19:46
 */


return array(

    'PAGE_SIZE' => 3
)

?>

然后在config.php加载此常量类

 'LOAD_EXT_CONFIG' => 'cons1,cons2',//多个文件用,隔开

最后类中使用C('PAGE_SIZE')
$p = parent::getpage($count,C('PAGE_SIZE'));

  1. checkbox用jq全选二次操作失效
    checkbox做删除操作出现了,第二次js失效问题,记录一下(果然好久没写js了,都忘了),原因是开始用的是attr,发现jquery1.6后checkbox此操作要改成prop,否则attr会有只有第一次有效的问题。
  function checkAll() {
        var checkAll = $("input[name='checkAll']").is(":checked");
        var boxes=$("input[name='userBox']");
        if(checkAll==true){
        // boxes.attr("checked",true); 原来写法,这样只有第一次生效
            boxes.prop("checked",true);//全选
        }else{
            boxes.prop("checked",false)
        }

    }

  1. session管理

thinkphp对session很简单,直接使用

    //取值
        $loginVo=session('loginVo');

  //存值
      session('loginVo',$result);

非特殊情况下sesion过期时间采用一样的配置,在config.php中

'SESSION_OPTIONS'=>array(
        'expire'=>C('_SESSION_TIMEOUT'),
    )

  1. 模型类定义

面向对象,少不了页面模型,如登录信息模型

<?php
/**
 * Created by PhpStorm.
 * User: kai.yang
 * Date: 2019-01-04
 * Time: 21:41
 */

namespace Model;

class LoginModel
{
    private $loginNmae;

    private $role;

    private $deploy_name;

    /**
     * LoginModel constructor.
     * @param $loginNmae
     * @param $role
     */
    public function __construct($loginNmae, $role,$deploy_name)
    {
        $this->loginNmae = $loginNmae;
        $this->role = $role;
        $this->deploy_name=$deploy_name;
    }


    /**
     * @return mixed
     */
    public function getLoginNmae()
    {
        return $this->loginNmae;
    }

    /**
     * @param mixed $loginNmae
     */
    public function setLoginNmae($loginNmae)
    {
        $this->loginNmae = $loginNmae;
    }

    /**
     * @return mixed
     */
    public function getRole()
    {
        return $this->role;
    }

    /**
     * @param mixed $role
     */
    public function setRole($role)
    {
        $this->role = $role;
    }

    /**
     * @return mixed
     */
    public function getDeployName()
    {
        return $this->deploy_name;
    }

    /**
     * @param mixed $deploy_name
     */
    public function setDeployName($deploy_name)
    {
        $this->deploy_name = $deploy_name;
    }



    public function __toString()
    {
        return "LoginMode=loginName:".$this->getLoginNmae().";role:".$this->getRole().";deploy_name:".$this->getDeployName();


    }



}

好了,遇到的问题,暂时整理到这里,大家可以参考源代码进行对应,希望对初学者有总结性的帮助。
目录:php学习路-- Thinkphp开发入门指南简介

相关文章

网友评论

      本文标题:php学习路(八) --Tp项目web工程总结

      本文链接:https://www.haomeiwen.com/subject/avddrqtx.html