php前置知识&留言板开发

154 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第八天,点击查看活动详情

PHP弱类型

弱类型引起的漏洞也是在CTF中经常遇到的,所以这一块是比较重要的

<?php
    $str = "123s"; 
/*
* ==会先转换为同一类型
* ===会进行类型和值的对比
*/
var_dump($str == 123);     //true
var_dump($str === 123);   //false
/*
* 0e开头都会被当成相同的值
*/
var_dump(0e1223 == 0e11111);    //true
//数组转换类型进行比较
var_dump(in_array("12adsa",[12]));     //true
?>

这里首先需要知道==和===的区别: ==进行比较时会先转换为同一类型之后进行比较,比如 "0admin" == 0 ,那么结果就是ture ===进行比较时候不仅对比值,还对比类型 PHP遇到0e时会认为是科学计数法,而0e后面加任何数都会被认为是0,这也就可以解释为什么0e111 == 0e222 而数组则是会将其进行类型转换,也就是为什么in_array("12adsa",[12])为ture 写到这就不得不提一下CTF中的md5绕过,也是使用的这种方法

    if(v1 !=v2 && md5(v1) == md5(v2)):
        { return true; } 
    if(md5((string)$_GET['a'])===md5((string)$_GET['b']))
    {
        var_dump($flag);
    }

md5不能处理数组,那么就可以使用v1[]=a&v2[]=a进行绕过,也可以使用0e进行绕过

异常处理

在异常处理这里,PHP和其他语言不一样的地方在于不能自动捕获异常 所以需要手动捕获,也就是首先使用函数try,catch输出异常完整信息;然后定义异常,代码为catch(FileExistException e);最后重抛异常给上层,代码为catch(Exceptione);最后重抛异常给上层,代码为catch(Exception e)

<?php
$arr = [1];
    try{
        if($arr[0]>0){
            throw new Exception("大于0抛出异常\n");
        }
    }catch(Exception $e){
        print $e->getMessage();
    }
    try{
        if(!isset($arr[2])){
            throw new Exception("数组下标越界! \n");
        }
    }catch(Exception $e){
        print $e->getMessage();
    }
?>

留言板

学到这里,在特特师傅的指导下写了个小项目,期间出了无数的bug,第一次开发,de了好几天才算是完美了 最终页面为:

第一次手写HTML,之前都是用的可视化界面(DW),这次尝试了手敲,也学到了很多,比如css样式等

功能介绍

该留言板简单实现了增删查改功能,前端采用html+css,后端使用的php(PHP是世界上最好的语言)

涉及知识有反序列化、文件操作、传参、流程控制等

实现逻辑

首先判断用户要进行的操作是什么(增、删、改)

根据用户操作分别对应功能点,id、ip、时间使用函数得到结果,留言人、留言内容均使用post传参,用户信息存储在json文件中方便调用

添加功能:

将用户输入的内容储存在messages数组中,判断是否存在数据储存文件infor.json,使用file_get_contents()函数获取内容,获取后将其反序列化保存到json文件

删除功能:

首先判断要删除的id是否与储存数组中的id相同,如果一致,通过遍历将其删除

更新功能:

首先判断要更新的id是否正确、json文件是否正确,将json内容反序列化后储存到数组中,根据用户的输入进行更新(留言人和留言内容)

源码

<?php
    if($_GET["act"]=="add") {
        session_start();
        if (!isset($_SESSION["id"])) {
            $_SESSION["id"] = 0;
        }
        //当前用户ip
        $ip = $_SERVER['REMOTE_ADDR'];
        //当前时间
        $time = date('Y-m-d h:i:s', time());
        //留言内容不能为空
        if(empty($_POST["username"]) || empty($_POST["message"])){
            print "<script>alert('您没有输入留言人名字或者留言内容');location.href='/php/study/MessageBoard.php?';</script>";
        }
        //将所有信息存储到数组中
        $messages = [
                "id"       => $_SESSION["id"] += 1,
                "username" => $_POST["username"],
                "message"  => $_POST["message"],
                "time"     => $time,
                "ip"       => $ip
        ];
        //判断是否存在存储数据文件,没有则新建
        if(!file_exists("infor.json")){
            fopen("infor.json", "w");
        }
        //file_get_contents:将整个文件读入到一个字符串中
        $content = file_get_contents("infor.json");
        //判断是否为空,不为空则将其反序列化并返回数组
        if(!empty($content)){
            $content = unserialize($content);
            $content[] = $messages;
            $content = serialize($content);
        }else{
            $content = serialize([$messages]);
        }
        //能否成功写入
        if(file_put_contents("infor.json", $content)){
            print "<script>alert('留言成功');location.href='/php/study/MessageBoard.php?';</script>";
        }
    //删除操作
    }else if ($_GET["act"] == "delete") {
        if(!isset($_GET["id"]) || empty($_GET["id"])){
            print "<script>alert('删除失败');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        if(is_file("infor.json")){
            $content = unserialize(file_get_contents("infor.json"));
        }
        //遍历,id相同则删除
        foreach ($content as $key => $value) {
            if ($value["id"] == $_GET["id"]) {
                unset($content[$key]);
                break;
            }
        }
        if (file_put_contents("infor.json", serialize($content))) {
            print "<script>alert('删除成功');location.href='/php/study/MessageBoard.php?';</script>";
        }
        die;
    //更新操作
    }else if ($_GET["act"] == "update") {
        if(!isset($_GET["id"]) || empty($_GET["id"])){
            print "<script>alert('ID为空');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        if (!is_file("infor.json")) {
            print "<script>alert('留言信息为空');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        $content = unserialize(file_get_contents("infor.json"));
        if (empty($content)) {
            print "<script>alert('留言信息为空');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        //写到数组message
        $message = [];
        foreach ($content as $value) {
            if($value["id"] == $_GET["id"]){
                $message = $value;
                break;
            }
        }
    }
        if (!empty($message)) {
?>
<h3>Edit Message</h3>
<form method="post" action="?act=doupdate&id=<?=$message['id']?>">
<fieldset>
<p>
    <label for="username">留言人:</label>
    <input type="text" id="username" name="username" value="<?=$message['username']?>" align="left">
</p>
<p>
    <label for="message">留言内容:</label>
    <textarea id="message" name="message"cols="30" rows="5" align="left"><?=$message['message']?></textarea>
</p>
<p>
    <input type="submit" name="submit" value="更新留言" >
</p>
</fieldset>
</form>
<?php    
    //更新成功与否操作    
    }else if($_GET["act"] == "doupdate"){
        if (!isset($_GET["id"]) || empty($_GET["id"])) {
            print "<script>alert('ID为空');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        if(empty($_POST["message"]) || empty($_POST["username"])){
            print "<script>alert('用户名或内容为空');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        if (!is_file("infor.json")) {
            print "<script>alert('更新失败');location.href='/php/study/MessageBoard.php?';</script>";
            die;
        }
        $content = unserialize(file_get_contents("infor.json"));
        $ip = $_SERVER['REMOTE_ADDR'];
        $time = date('Y-m-d h:i:s', time());
        if (!empty($content)) {
            foreach ($content as $key => $value) {
                if ($value['id'] == $_GET['id']) {
                    $content[$key] =[
                        "id"       => $value['id'],
                        "username" => $_POST['username'],
                        "message"  => $_POST['message'],
                        "ip"       => $ip,
                        "time"     => $time
                    ];
                }
            }
        }
            if (file_put_contents("infor.json", serialize($content))) {
                print "<script>alert('更新成功');location.href='/php/study/MessageBoard.php?';</script>";
                die;
            }else{
                print "<script>alert('更新失败');location.href='/php/study/MessageBoard.php?';</script>";
            }
            die;
    }else{
        $content = [];
        if(is_file("infor.json")){
            $content = unserialize(file_get_contents("infor.json"));
        }
?>

<!DOCTYPE html>
<html>
<head>
    <title>My MessageBoard</title>
</head>
<body>
    <style type="text/css">
        body{
            font-size: 100%;
            font-weight: normal;
            text-align: center;
            background: #FFCCCC;
        }
        h2{
            text-align: center;
        }
        table{
            width:65%;
            margin: 0 auto;
            border-collapse: collapse;
        }
        td{
            text-align: center;
            border-top: 1px solid black;
        }
        tr:hover td{
            background-color: #FFCC99;
            color:white;
        }
        form{
            margin: 40px;
        }
        fieldset{
            background-color: #FFC0CB;
            border: none;
            border-radius: 2px;
            margin-bottom: 12px;
        }

        label{
            display: inline-block;
            padding: 3px 6px;
            text-align: right;
            width: 150px;
            vertical-align: top;
        }

        input{
            font-size: inherit;
        } text-align: right;
        }
    </style>
    <h2> My MessageBoard</h2>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>留言人</th>
                <th>留言内容</th>
                <th>留言时间</th>
                <th>留言人IP</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <?php
                if(!empty($content)){
                    foreach ($content as $value) {
            ?>
            <tr>
                <td><?=$value['id']?></td>
                <td><?=$value['username']?></td>
                <td><?=$value['message']?></td>
                <td><?=$value['time']?></td>
                <td><?=$value['ip']?></td>
                <td><a href="?act=update&id=<?=$value['id']?>">编辑</a>|<a href="?act=delete&id=<?=$value['id']?>">删除</a></td>
            </tr>
        <? }} ?>
        </tbody>
    </table>
    <form method="post" action="?act=add">
         <fieldset>
        <p>
            <label for="username">留言人:</label>
            <input type="text" id="username" name="username" align="left">
        </p>
        <p>
            <label for="message">留言内容:</label>
            <textarea id="message" name="message" cols="30" rows="5" align="left"></textarea>
        </p>
        <p>
            <input type="submit" name="submit">
        </p>
        </fieldset>
    </form>
<? } ?>
</body>
</html>