PHP论坛开发技术总结

1,132 阅读4分钟

Bootstrap

本项目的前端都是通过Bootstrap来实现,我们只需要在页面头部加载Bootstrap的层级样式表,即可非常快捷地使用Bootstrap的组件

<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

Bootstrap官方文档:v3.bootcss.com/

图片上传

我实现图片上传的思路如下:

  • 前端打开文件,获取文件信息

    <div id="file">
    <input id="inpfile" type="file" accept="image/gif, image/jpeg, image/png" name="file"> 
    <button type="button" class="btn btn-default btn-lg">
    <span class="glyphicon glyphicon-picture" aria-hidden="true"></span>
    </button>
    </div>
    
  • 通过ajax技术将图片发给后端

    $( document ).ready(function(){
              $('#inpfile').change(function(){    
              
                var file_data = $('#inpfile').prop('files')[0];   
                var form_data = new FormData();                  
                form_data.append('file', file_data);
              
                  $.ajax({
                  url:'pic.php',
                  type:'POST',
                  dataType: 'text',  
                  cache: false,
                  contentType: false,
                  processData: false,
                  data:form_data,
    
          success:function(data1){
    
              var pic = "<br><img src ="+data1+" /><br>"
    
              document.execCommand("insertHTML","false",pic);
    
          }
    
              });
    
    })
      })
    
  • 后端处理并存储图像(放在服务器或本地的某个文件夹)

    $imgname = $_FILES["file"]["name"]; //获取上传的文件名称
    $filetype = pathinfo($imgname, PATHINFO_EXTENSION);//获取后缀
    $newname = date("Ymdhis").".".$filetype; 
    //构建新名称
    $_FILES['file']['name'] = $newname;
    // 构建传输路径
    $dir = 'img/'.iconv('UTF-8','gbk',basename($_FILES['file']['name'])); 
    // 将路径存入数据库
    $result = mysqli_query($conn, "UPDATE  users SET tx = '{$dir}' WHERE id = '{$id}'");
    // 移动文件到指定路径
    move_uploaded_file($_FILES['file']['tmp_name'],$dir);        
    echo $dir;
    

表单与后端

1.构建表单
<form action="" method="POST">
	<input type="text" class="form-control" placeholder="君の名は?" aria-describedby="basic-addon1" name="name" >
    <input type="password" class="form-control" placeholder="Password" aria-describedby="basic-addon1" name="password">
    <button type="submit" class="btn btn-default">注册</button>
</form>
  • from标签:表单标签,action属于填发送信息的后端文件(login.php),空白则发给自己;method属性确定发送信息的方式,一般表单都用"POST"
  • input标签:设置一个表单域,type属性为表单填写的数据类型(甚至有密码和日期等内置的类型),placeholder属性即表单域提示文字,name属性为该表单域数据起名方便后端识别
  • button标签:当button放在from标签内,且type属性为“submit”,可以起到提交表单信息到后端的功能
2.后端接收表单信息
$name = $_POST["name"];
$password = $_POST["password"];
3.表单重复提交问题

表单与后端交互时会出现一个经典的问题:当页面刷新是,表单会重复提交用户输入的数据,导致出现插入重复的数据或者发出空白数据这样的问题

这个问题的解决方案有很多,这里提供两种简单的解决方案

  • 页面重定向

    最简单最有效的解决方法,在用户提交表单后,立刻重定向到新页面或者到本页面

    header("refresh:1; url=login.php"); 
    

    问题:一个页面不能有多个重定向,否则会报错

  • js代码禁止页面刷新

    一种比较奇葩的思路,但是某些时候会十分有效

    if (window.history.replaceState ) {
            window.history.replaceState( null, null, window.location.href );
     }
    
  • 参考文章(更多解决方案)

    一些大佬们的讨论:stackoverflow.com/questions/6…

    总结得比较好的文章:makitweb.com/prevent-pag…

前端发送信息的其他方式

表单提交信息到后端有个致命的问题,那就是每一次提交都需要刷新一次页面,这种现象叫同步请求。

但是很多时候我们只需要局部刷新页面,这时候就需要用到异步请求了。

JavaScript中的Ajax技术就可以实现这样的异步请求,其相当于在表单与后端之间加入一个干活更加利索的信息搬运工

1.js实现Ajax

js实现Ajax技术需要用到XMLHttpRequest()对象

ajax的工作过程:

  • 创建XMLHTTPRequest对象
  • 设置请求的url等参数
  • 发送请求
  • 注册事件
  • 在注册事件中获取返回的内容,并修改页面显示,实现局部刷新

我们一般用post的方式,前端send发送,后端$_POST,最后一个echo返回数据,前端ajax.responseText接收返回数据

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>post方式发送数据</title>

</head>
<body>
    <h1>注册名字</h1>
    <input type="text" name="userName" id="btnName"><label id="tishi" style="display:none"></label>

</body>
</html>
<script>

    //绑定失去焦点事件
    document.querySelector('#btnName').onblur=function(){
      // 发送ajax请求到服务器
      //1.创建异步对象
      var ajax = new XMLHttpRequest();
      //2.设置请求的url等参数
      ajax.open('post','example.php');
      /*如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:*/
      ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
      // 3.发送请求
      ajax.send('Name='+document.querySelector('#btnName').value);

      // 4.注册事件
      ajax.onreadystatechange = function(){
        if (ajax.readyState ==4&&ajax.status==200) {
            // 5.在注册事件中接收返回的内容并修改数据
            console.log(ajax.responseText);
            var show = document.querySelector('#tishi');
                show.style.display='block';
            if (ajax.responseText =="exist") {

                show.innerHTML='该用户已经注册了!'

            } else{
                show.innerHTML='你可以使用该名字!'
            }
        }
      };

    }
</script>

后端:

<?php

     header('content-type:text/html;charset=utf-8');
     $name=$_POST['Name'];


     // 准备一个数据 模拟已经存在的用户
     $nameArray = array('jack','kong','rose','ice');

     // 检验是否存在,并且接受返回值
     $result=in_array($name, $nameArray);
     // 通过if else返回不同的值给浏览器
     if($result){
     echo "exist";
     } 
	 else{
     echo "not exist";
     }


?>

参考文章:blog.csdn.net/diligentkon…

2.jquery实现Ajax

相对于原生的js,jq实现Ajax的方法无疑简单很多,也是本项目主要使用的方法

  • 首先使用jq需要引入jq的文件

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
  • 然后使用jq构造Ajax

    前端

    $.ajax({
        // 请求的后端文件
    	url:'love.php',
        // 请求方式
        type:'POST',
        // 发送的数据
        data:{id:id, choose:tj_count},
    	
        // 成功发送后触发的函数,data2为后端返回的数据
        success:function(data2){
        	//修改文本不能用直接等于
        	$(e).find('.badge').text(data2)
          }
     });
    

    后端

    // 接收前端ajax发来的数据
    $id = $_POST["id"];
    $choose = $_POST["choose"];
    if(id==1 && choose==1){	
    	$num = 2
    }
    // 返回数据
    echo $num;
    

后端获取信息的其他方式

除了从前端的表单中获取,后端还可以从url,cookie和session中获取信息,当然还有存储信息更为强大的数据库(这里先不讲,后面单独会有专题)

1.以GET的形式获取url中的信息

通过这种方法可以渲染出数据不同的页面,如文章页,个人主页。

  • 前端构造url

    <a href="passage.php?id='.$passage_row["id"].'&method=2" />
    

    '?'后面是数据,如method的值为'2'

  • 后端获取数据

    $id = $_GET["id"]; 
    
2.把信息存在cookie中

cookie是将用户信息储存在客户端即浏览器中,供各个页面使用这些在cookie中存储的数据

cookie具备有效期,当有效期结束之后,Cookie会自动的从客户端删除

cookie的数据极易被修改,所以一般来说不会把敏感信息和重要信息存在cookie中

  • 创建cookie

    设置一个名叫"userid"的数据,值为$row["id"]

    setcookie("userid", $row["id"])
    

    也可以通过header来设置cookie

    header("Set-Cookie:cookie_name=value");
    
  • 读取cookie

    $belong_id = $_COOKIE["userid"];
    
3.把信息存在session中

如果说cookie相当于存折,可以看到里面的信息。那么session就像银行卡,你只能用而不能看到被加密的信息,所以信息安全性会更高

  • 创建session

    session_start();
    $_SESSION['sessionName'] = 'sessionValue';
    echo "session_id:".session_id(); // 显示当前的session_id
    echo "<br>";
    
  • 读取session

    $session = $_SESSION['sessionName'];
    

PHP请求API

1.file_get_contents请求API

file_get_contents请求api的方法相对简单,适合请求相对简单的api和网页页面

// 请求api
$api = file_get_contents("http://api.bilibili.com/x/emote/user/panel/web?business=reply");
// 将api返回的数据转换为json数据处理
$data =json_decode($api, true);
// 索引json中的数据
$str =  $data ["data"]["packages"][$num]["emote"];
2.curl请求API

curl来请求api才是主流的方法

// 创建一个curl的会话
$ch = curl_init();
// 设置请求的URL
curl_setopt($ch, CURLOPT_URL, "http://api.gochati.cn/htapi.phpq='{$str}'&token=test123");
// 设置否将响应结果存入变量,1是存入,0是直接echo出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 得到响应结果存入变量中
$output = curl_exec($ch);
echo $output;
// 关闭这个curl会话
curl_close($ch);    

把信息存在数据库

终于来到本文的重头戏了——数据库,后端处理完数据后就可以将数据存在数据表中,方便下一次去使用,更重要的在于可以构建数据间的关系。

本项目用了面向过程的方法,其实和面向对象差别不大

1.连接数据库
$servername = "127.0.0.1";//以下四行为数据库信息
$user = "user";//用户名
$password_all = "123456";//密码
$data = "acg";//要使用的数据库名称

// 创建连接
$conn = mysqli_connect($servername, $user, $password_all, $data);

// 检测连接
if (!$conn) {
    die("连接失败: " . mysqli_connect_error());
} 
echo "连接成功";
// 修改字符集的编码方式,现在不推荐使用
mysqli_query($conn,"set names 'utf8';");
2.创建数据表

一般的数据表可以提前建好,不用代码来形成。可以使用如Navicat等可视化mysql工具

建表注意事项:

  • 表的字段名不要与语言的关键字重复
  • 主键只能设一个,一般设id为主键
  • 注意数据类型和长度,一般的整型数据长度用1,短的字符串用varchar类型,如果要存储文章之类的则需要text类型,长度设为0
  • 字符串的字符集一般是utf8,排序规则一般utf8_general_ci
  • 设置能否为null是特别容易出错的地方,如果设置为不是null即该数据不能为空,在插入数据时如果该数据不插入则会出现数据无法插入的错误(但是是不会报错的(:)
3.插入数据
$query = mysqli_query($conn,"INSERT INTO wz (sj, ht, ms, zz, pl, tj) VALUES ( '$time' ,'{$topic}','{$passage}', '{$name}', 0, 0);");
  • mysqli_query是对连接的数据库执行sql语句
  • sql语句,INSERT INTO即执行插入命令
  • wz指插入的对象表格,(sj, ht, ms, zz, pl, tj)则是表格的字段,注意如果构建表时设置了某字段为不为null,则该字段一定要填入其中,否则所有的数据都无法插入
  • VALUES 后面即字段对应的值
4.读取数据

本项目用的最频繁的一定是读取mysql数据了,而且还非常频繁地使用了禁术SELECT * (:

$passage_result = mysqli_query($conn, 'SELECT * FROM wz;');
while( $passage_row = mysqli_fetch_assoc($passage_result)){
    if($passage_row["id"] == $id ){
        if($choose == 0){   
            $num =  ++$passage_row['tj'];
        }
        else {   
             $num =  --$passage_row['tj'];
        }
	}
  • SELECT * FROM搜索整个表格的所有字段,但里面填写了字段名,则只搜索该表的该字段。最终整合成一堆关联数组
  • from后面接数据表名
  • mysqli_fetch_assoc提取出一条关联数组
  • while( $passage_row = mysqli_fetch_assoc($passage_result))逐个遍历之前生成一堆关联数组
  • $passage_row["id"]索引一条关联数组的id
5.整合数据
$result  = mysqli_query($conn, "select * from comment where passage_id = '{$id}'");
$all = mysqli_num_rows($result);
echo $all;

where可以达到批量操作同一个数据表的多个数据的操作,也常常用于统计数据表的相同数据

6.更新数据
//查询插入即更新已有数据
$comment_add = mysqli_query($conn, "UPDATE wz SET pl = '{$all}' WHERE id = '{$id}' ");

update比较简单,值得一提的是,它可以和where结合更新指定数据(相当于if的作用,还不用遍历)