繁体   English   中英

PHP认为它正在写入.txt文件,但实际上不是

[英]PHP thinks it is writing to a .txt file, but it is actually not

我目前正在写一个小型网站,每个人都可以在上面设置是否存在。 该网站的每个访问者都可以看到谁在场,谁不在场。 有一个小的开关(带有CSS的复选框)指示存在。

我现在正在处理的事情是一个switch(复选框),它将记住页面重新加载时的状态。 我这样做的方法是通过写入服务器“ true”或“ false”上的简单.txt文件。 在启动时,它将读取文本文件的状态。 我还提供了许多控制台注释,以查看错误所在,但现在即时通讯卡住了。

在注释的结尾,更改复选框时,它将读取带有fread的.txt文件,以检查fwrite是否有效。 在控制台中,它表示已正确写入(.txt文件根据上一次写入读取了该变量。)但是,如果我通过网站www.example.eg/textfile.txt访问该文件,则表示它没有改变了。 同样,复选框状态不会在重新加载页面时保存。

<!DOCTYPE html>
<html>
    <head>


        <script>
        function startupfunction(){
        <?php //reading current state
        $myfile = fopen("switchstate.txt", "r") or die("Unable to open file!");
        $output = fread($myfile,filesize("switchstate.txt"));

        // $output = "42";
        ?>

        var data = '<?php echo $output; ?>';
        var startupsetting;

        console.log("the initial (startupfunction) reading out of .txt(var = data):" + data);
        if(data == "true"){
            console.log("The if(true) statement based on var data works. setting bool to TRUE to change to correct switchstate")
            startupsetting = true;
        }
        else{
            console.log("The if(true) statement based on var data works. setting bool to FALSE to change to correct switchstate")
            startupsetting = false;
        }
        document.getElementById("myCheck").checked=startupsetting;
        console.log("This is done by setting a bolleaan called startupsetting this is now equal to:" + startupsetting);

        var x = document.getElementById("myCheck").checked;
        console.log("Now reading the state of the switch? did it work (is it equal to line above)" + x)
        } //close startupfunction


        window.onload = startupfunction;                    //set state of checkbox(switch)

        </script>
        </head>

<body>




<style>                                                                                             
    .onoffswitch {
    position: relative; width: 90px;
    -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
    display: none;
}
.onoffswitch-label {
    display: block; overflow: hidden; cursor: pointer;
    border: 2px solid #999999; border-radius: 20px;
}
.onoffswitch-inner {
    display: block; width: 200%; margin-left: -100%;
    transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
    display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
    font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
    box-sizing: border-box;
}
.onoffswitch-inner:before {
    content: "WEL";
    padding-left: 10px;
    background-color: #34A7C1; color: #FFFFFF;
}
.onoffswitch-inner:after {
    content: "NIET";
    padding-right: 10px;
    background-color: #EEEEEE; color: #999999;
    text-align: right;
}
.onoffswitch-switch {
    display: block; width: 18px; margin: 6px;
    background: #FFFFFF;
    position: absolute; top: 0; bottom: 0;
    right: 56px;
    border: 2px solid #999999; border-radius: 20px;
    transition: all 0.3s ease-in 0s; 
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
    margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
    right: 0px; 
}
</style>




<div class="onoffswitch">
    <input onchange="myFunction();" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myCheck">
    <label class="onoffswitch-label" for="myCheck">
        <span class="onoffswitch-inner"></span>
        <span class="onoffswitch-switch"></span>
    </label>
</div>




<script>
function myFunction() {
    var x = document.getElementById("myCheck").checked;
    console.log("now starting measuring changes, x value changing...")
    console.log("Value of x before flipping:"+ x);
    x = (x) ? false : true;
    console.log("Value of x after flipping:" + x);

    //if(x==true) blaablaablaa
    if(x == true){
            <?php   //write 0 back to .txt file onserver
            $myfile = fopen("switchstate.txt", "w") or die("Unable to open file!");
            $txt = "false";
            fwrite($myfile,$txt);

            ?>

            console.log("wrote false(using the if/true statement) to .txt...");
            console.log("starting reading .txt file")

            <?php //reading current state
            $myfile = fopen("switchstate.txt", "r") or die("Unable to open file!");
            $output = fread($myfile,filesize("switchstate.txt"));

            // $output = "42";
            ?>

            var data = '<?php echo $output; ?>';
            console.log("the .txt file now reads:" + data);

    }

    else{
            <?php   //write 0 back to .txt file onserver
            $myfile = fopen("switchstate.txt", "w") or die("Unable to open file!");
            $txt = "true";
            fwrite($myfile,$txt);

            ?>
            console.log("wrote true(using the else/false statement) to .txt...");
            console.log("starting reading .txt file")

            <?php //reading current state
            $myfile = fopen("switchstate.txt", "r") or die("Unable to open file!");
            $output = fread($myfile,filesize("switchstate.txt"));

            // $output = "42";
            ?>

            var data = '<?php echo $output; ?>';

            console.log("the .txt file now reads:" + data);

    }


}
</script>
</body>
</html>

TL; DR,您需要加强客户端/服务器编程以及PHP代码的AJAX回调。 推荐了有关PHP和jQuery的教程。 我在这里走了个弯路,建议您访问http://www.w2ui.com进行界面开发( 并且现在我会被每个建议最喜欢的框架或库的人大吃一惊;-)


实际上,您至少需要两个文件。 仅第二个需要是PHP。 首先,在Javascript中,您将截取复选框更改。

通常这是使用jQuery或类似方法完成的,因为它使这种事情变得非常容易:

// this will only work if jQuery is loaded
$('#idOfMyCheckbox').on('change', function() {
    $.post(
        '/url/of/my/checkbox/saver',
        {
            state: $(this).val()
        },
        function(ret) {
            alert("The server replied: " + ret.message);
        }
    ).fail(function() {
        alert("something went very wrong");
    });
});

PHP由$.post AJAX调用,并将收到$_POST['state']值。

<?php
     $fp = fopen("state.txt", "w");
     fwrite($fp, $_POST['state']); // DANGER WILL ROBINSON: NO ERROR CHECKING HERE.
     fclose($fp);
?>

调试

拥有应用程序后,您需要知道它的实际作用 例如,加载上面的代码(一旦您提供了正确的HTML,jQuery绑定等),除了加载所需的资源外, 什么都不做。

然后,更改复选框的状态应触发到状态保存URL的HTTP POST。

为了验证这一点,您会发现Chrome的WebTools或Firefox的Firebug扩展很有用。 我猜您自发出console.log调用以来已经在使用类似的东西。 这些工具还记录资源使用情况和错误。

它们还允许您从控制台界面发出呼叫,因此您可以例如运行

$('#idOfYourCheckbox')

并验证它返回的数组中只有一个对象(否则,选择器出了点问题。我通常复制并粘贴并最终得到<input id="#myId">而不是<input id="myId"> ,例)。

然后,您可以手动发出.post调用,并验证它是否熄灭以及系统返回什么。 上面,我没有费心添加AJAX查询所需的JSON返回:

 fclose($fp);
 Header("Content-Type: application/json;charset=utf-8");
 die(json_encode(array(
     'status'  => 'OK',
     'message' => 'It worked!',
 )));

(我这样做是出于懒惰。我的错。但是,所有这一切都表明,您不应该期望只是在网站中插入一段代码并使之正常工作-您需要知道它的作用, 它的作用是什么。可以做到 ,即使那样,您也需要花很多时间来弄弄它)。

独立的示例(也带有状态加载)

<html>
    <head>
        <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    </head>
    <body>
        <input id="mycheck" type="checkbox" />
    </body>
    <script>
        // jQuery main function
        jQuery(document).ready(function($) {

            /* Call this function on every change of myCheck.
               Since it is bound to #mycheck, inside the function
               'this' refers to the checkbox, and $(this) is the
               jQuery object mapping the checkbox.
            */
            $('#mycheck').on('change', function(e) {
                $.post(
                    'test.php',
                    {
                         cmd        : "set",
                         state      : $(this).prop("checked"),
                         timestamp  : new Date().getTime(),
                         hello      : "world"
                    },
                    function(reply, textStatus, jqXHR) {
                        if (!reply.hasOwnProperty('message')) {
                            console.log("the server replied with no message");
                            return;
                        }
                        console.log("the server replied: " + reply.message);
                    }
                ).fail(function(e) {
                    alert("Something went wrong");
                });
            });

            /* Now we also want to know what the status is NOW. */
            $.post(
                'test.php',
                {
                     cmd        : "get",
                     timestamp  : new Date().getTime()
                },
                function(reply, textStatus, jqXHR) {
                    if (!reply.hasOwnProperty('state')) {
                        console.log("the server replied with no state");
                        return;
                    }
                    // If the server replied TRUE we set state to true.
                    // Else to false.
                    $('#mycheck').prop('checked', reply.state);
                }).fail(function(e) {
                    alert("Something went wrong");
                });

        });
    </script>
</html>

在PHP方面,我们将在test.php中接收命令:

<!-- lang: lang-php5 -->
<?php
    function reply($reply) {
        Header("Content-Type: application/json;charset=utf-8");
        die(json_encode($reply));
    }
    function replyError($message) {
        return reply(array('status' => 'error', 'message' => $message));
    }
    function replySuccess($data, $message = '') {
        return reply(array_merge(
            array('status' => 'success', 'message' => $message),
            $data
        ));
    }

    array_key_exists('cmd', $_POST) || replyError('cmd not set');

    switch($_POST['cmd']) {
        case 'set':
            $fp = fopen('state.txt', 'w');
            $state = in_array($_POST['state'], array(1, "1", "true", true));
            fwrite($fp, $state ? "CHECKED" : "NOT CHECKED");
            fclose($fp);
            replySuccess(array('state' => $state));
        case 'get':
            if (!file_exists('state.txt')) {
                $state = false;
            } else {
                $text = file_get_contents('state.txt');
                $state = ('CHECKED' == $text);
            }
            replySuccess(array('state' => $state));
        default:
            replyError("cmd={$_POST['cmd']} is not recognized");
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM