简体   繁体   English

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

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

I am currently writing a small website on which everybody can set if they will be present or not. 我目前正在写一个小型网站,每个人都可以在上面设置是否存在。 Every visitor of the site can see who is going to be present and who is not. 该网站的每个访问者都可以看到谁在场,谁不在场。 there is a small switch (a checkbox with CSS going over it) which indicates presence. 有一个小的开关(带有CSS的复选框)指示存在。

The thing i'm working on right now is a switch(checkbox) which will remember the state that it's in on page reload. 我现在正在处理的事情是一个switch(复选框),它将记住页面重新加载时的状态。 The way i've done this is by writing to a simple .txt file on the server 'true' or 'false'. 我这样做的方法是通过写入服务器“ true”或“ false”上的简单.txt文件。 At startup it reads the state of the textfile. 在启动时,它将读取文本文件的状态。 i also included a lot of console comments to see where it is going wrong, but now im stuck. 我还提供了许多控制台注释,以查看错误所在,但现在即时通讯卡住了。

At the end of the comment when the checkbox is changed, it reads the .txt file with fread to check if fwrite worked. 在注释的结尾,更改复选框时,它将读取带有fread的.txt文件,以检查fwrite是否有效。 In the console it says that it wrote correctly (the .txt file reads the variable that it should according to the last writing.) But if I access the file trough my site www.example.eg/textfile.txt it says it hasn't changed. 在控制台中,它表示已正确写入(.txt文件根据上一次写入读取了该变量。)但是,如果我通过网站www.example.eg/textfile.txt访问该文件,则表示它没有改变了。 Also the checkbox state isn't saved on reload of the page. 同样,复选框状态不会在重新加载页面时保存。

<!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 you need to beef up on client/server programming and AJAX callback to PHP code. TL; DR,您需要加强客户端/服务器编程以及PHP代码的AJAX回调。 Recommended a tutorial on PHP and jQuery. 推荐了有关PHP和jQuery的教程。 I'm going out on a limb here and suggest you check out http://www.w2ui.com for interface development ( and I'll now be flamed by everyone suggesting their favourite framework or library ;-) ) 我在这里走了个弯路,建议您访问http://www.w2ui.com进行界面开发( 并且现在我会被每个建议最喜欢的框架或库的人大吃一惊;-)


You actually need two files (at least). 实际上,您至少需要两个文件。 Only the second needs to be PHP. 仅第二个需要是PHP。 In the first, in Javascript, you intercept the checkbox change. 首先,在Javascript中,您将截取复选框更改。

This is usually done using jQuery or similar, because it makes this kind of things very easy: 通常这是使用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");
    });
});

The PHP is called by the $.post AJAX, and will receive a $_POST['state'] value. PHP由$.post AJAX调用,并将收到$_POST['state']值。

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

Debugging 调试

Once you have your application, you need to know what it actually does . 拥有应用程序后,您需要知道它的实际作用 For example, loading the code above (once you supply it with the proper HTML, jQuery bindings etc.) should do exactly nothing , apart from loading the needed resources. 例如,加载上面的代码(一旦您提供了正确的HTML,jQuery绑定等),除了加载所需的资源外, 什么都不做。

Then, changing the state of the checkbox should trigger a HTTP POST to the state-saving URL. 然后,更改复选框的状态应触发到状态保存URL的HTTP POST。

To verify this you will find useful either Chrome's WebTools or Firefox's Firebug extension. 为了验证这一点,您会发现Chrome的WebTools或Firefox的Firebug扩展很有用。 I guess you're already using something similar since you issue console.log calls. 我猜您自发出console.log调用以来已经在使用类似的东西。 These tools also log resource usage and errors. 这些工具还记录资源使用情况和错误。

They also allow you to issue calls from the console interface, so you can eg run 它们还允许您从控制台界面发出呼叫,因此您可以例如运行

$('#idOfYourCheckbox')

and verify it returns an array with exactly one object (otherwise, something went wrong with the selectors. I usually copy and paste and end up with <input id="#myId"> instead of <input id="myId"> , for example). 并验证它返回的数组中只有一个对象(否则,选择器出了点问题。我通常复制并粘贴并最终得到<input id="#myId">而不是<input id="myId"> ,例)。

Then you can manually issue the .post call, and verify that it goes out and what the system returns. 然后,您可以手动发出.post调用,并验证它是否熄灭以及系统返回什么。 Above, I had not bothered adding the JSON return that the AJAX query requires: 上面,我没有费心添加AJAX查询所需的JSON返回:

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

(I did it out of laziness. My bad. But it all goes to show that you shouldn't expect to just plug a piece of code in the site and have it working -- you need to know what it does, what it is expected to do , and even then you'll need to fiddle with it a good bit). (我这样做是出于懒惰。我的错。但是,所有这一切都表明,您不应该期望只是在网站中插入一段代码并使之正常工作-您需要知道它的作用, 它的作用是什么。可以做到 ,即使那样,您也需要花很多时间来弄弄它)。

Self-contained example (with status loading too) 独立的示例(也带有状态加载)

<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 side we will receive commands into test.php: 在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