PHP:复选框isset总是返回true


PHP: checkbox-isset always returns true

在我的表单(我通过POST使用jQuery的ajax()提交)中,我有以下复选框(用于检查新用户是否应该具有管理权限):

<form action="../inc/new_user.php" id="new_user_form">
    Username:<br><input type="text" name="username" placeholder="Username"><br><br>
    Email:<br><input type="text" name="email" placeholder="Email"><br><br>
    Password:<br><input type="password" name="password" placeholder="Password"><br><br>

    <!-- here's the checkbox -->
    Admin: <input type="checkbox" name="admin" /><br><br>
    <input type="submit" value="Save">
</form>

然后我发布值(所有其他字段都很好,只是复选框没有):

$( "#new_user_form" ).submit(function( event ) {
      event.preventDefault();
      var $form = $( this ),
        username = $form.find( "input[name='username']" ).val(),
        email = $form.find( "input[name='email']" ).val(),
        password = $form.find( "input[name='password']" ).val(),
        admin = $form.find( "input[name='admin']" ).val(),
        url = $form.attr( "action" );
      var posting = $.post( url, { username: username, email: email, password: password, admin:admin } );
      posting.done(function( data ) {
        $( "#message_dialog" ).empty().append( data );
        $ ("#message_dialog" ).dialog({
          modal: true,
          buttons: {
            Ok: function() {
              $( this ).dialog( "close" );
            }
          }
        });
      });
    });

该代码用于获取PHP中的值:

$user_username      =   $_POST['username'];
$user_email     =   $_POST['email'];
$user_password      =   $_POST['password'];
if (isset($_POST['admin'])) {
    $user_admin = 1;
} else {
    $user_admin = 0;
}

但是,当我回显$user_admin时,无论复选框的状态如何,我总是得到"1"。这很奇怪,因为我多次被告知,如果取消选中复选框,就不会设置$_POST值。

我还尝试在输入元素上使用value属性,并在PHP中进行了比较。我的方法都不起作用,这让我现在发疯了。

注意:我将php变量$user_admin设置为0或1,以将其作为TINYINT存储在我的数据库(MySQL)中。1表示"是的,用户是管理员",0表示"不,他不是管理员"。

请告诉我这里出了什么问题。

您可能想要一个布尔值来告诉您是否选中了复选框:

admin = $form.find( "input[name='admin']" ).is(':checked'),

然后在PHP 中检查

if (isset($_POST['admin']) && $_POST['admin']) {

首先,admin = $form.find( "input[name='admin']" ).val()将始终返回'on',因为无论是否检查,您都不会得到它。解决此问题的一种方法是将末尾更改为admin = $form.find( "input[name='admin']" )[0].checked,这将为true|或|false

其次,因为您将数据作为admin: admin传递,所以您的服务器端将始终isset($_POST['admin'])作为TRUE|或|1,因为从技术上讲,它是设置的。当您以admin: admin的形式手动发送数据时,您会告诉服务器端,"嘿,这里有一个名为admin的键,我正在发送一个名称为admin的JS变量的值!"因此,它是isset

为了避免这种情况,您可以使用jQuery的.serializeArray()来获得与form正常提交(aka, not using e.PreventDefault)相同的值。因此,您的重写可以简单到:

$( "#new_user_form" ).submit(function( event ) {
    event.preventDefault();
    var $form = $(this),
        $data = $form.serializeArray(),
        url = $form.attr( "action" );
    var posting = $.post(url, $data);
    posting.done(function(data) {
        $( "#message_dialog" ).empty().append(data).dialog({
            modal: true,
            buttons: {
                Ok: function() {
                    $( this ).dialog( "close" );
                }
            }
        });
    });
});

这也意味着,if (isset($_POST['admin']))也将如您所期望的那样工作。


提示:请记住,只需在收集的数据中添加一个name/value object,就可以将数据添加到表单的序列化数组中。例如,从上面我们得到了$data = $form.serializeArray()。如果你想给从表单中收集的数据添加另一个值,那么你只需要:

$data[$data.length] = { name: 'bob', value: 'hello world' };

因此现在提供另一个值服务器端读作:$_POST['bob']

if (isset($_POST['admin'])) {
    $user_admin = 1;
} else {
    $user_admin = 0;
}

这意味着$_POST是否具有复选框值并且在您的页面中,复选框始终处于$_POST中,但其状态值不同你可以试试这个

if ($_POST['admin']) {
    $user_admin = 1;
} else {
    $user_admin = 0;
}

这是因为您将值作为空字符串发送(请参阅下面的示例),请尝试使用strlen($var)===0检查其是否为空。这段代码:

  var posting = $.post( url, { username: username, email: email, password: password, admin:admin } );

将发送这样的数据:

$_POST['username'] = "foo";
$_POST['email'] = "bar";
$_POST['password'] = "foobar";
$_POST['admin'] = ""; // empty string! Because it has no value