php
  • mysql
  • ajax
  • 2017-04-26 55 views 0 likes 
    0

    我创建一个记录系统,为此,我希望用户保存的个人资料图片带基本信息(姓名,用户名,密码)一起发送图像。对于这一点,我已经编写了以下文件:PHP - 无法通过mysqli_stmt_send_long_data

    HTML表单(在的index.php):

    <form id='signupform' enctype="multipart/form-data"> 
          <table style='margin: 0px auto; border-collapse: separate; border-spacing: 0 1em; color: #ffffff;'> 
          <tr> 
           <th colspan='2'> 
           <h2>SIGN UP</h2> 
           <p> 
            Please fill out ALL the fields 
           </p> 
           </th> 
          </tr> 
          <tr> 
           <td colspan='2'> 
           <div id='signuperror' style='display: block; width: 100%; height: 20px; border: 2px solid #ff0000; border-radius: 10px; background-color: #ffffff; color: #ff0000; text-align: center; opacity: 0;'>Username is taken!</div> 
           </td> 
          </tr> 
          <tr> 
           <td style='text-align: right;'> 
           First Name: 
           </td> 
           <td> 
           <input id='fname' type='text' name='first' placeholder='First Name' onkeyup="checkComplete('signup');" /> 
           </td> 
          </tr> 
          <tr> 
           <td style='text-align: right;'> 
           Last Name: 
           </td> 
           <td> 
           <input id='lname' type='text' name='last' placeholder='Last Name' onkeyup="checkComplete('signup');" /> 
           </td> 
          </tr> 
          <tr> 
           <td colspan='2' style='text-align: center;'> 
           <input id='usrimg' type='file' accept='image/*' name='userimage' style='display: none;' /> 
           <table style='width: 100%;'> 
            <tr> 
            <td style='width: 90%;'> 
             <button type='button' class='popbtn' onclick='browseImage();' style='width: 100%;'>Profile Image</button> 
            </td> 
            <td style='width: 10%;'> 
             <img id='imgstats' style='vertical-align: middle; display: none;' src='imgsuccess.png' /> 
            </td> 
            </tr> 
           </table> 
           </td> 
          </tr> 
          <tr> 
           <td style='text-align: right;'> 
           Username: 
           </td> 
           <td> 
           <input id='username' type='text' name='uid' placeholder='Username' onfocusout="checkUID(this.value);" onkeyup="checkComplete('signup');" /> 
           </td> 
          </tr> 
          <tr> 
           <td style='text-align: right;'> 
           Password: 
           </td> 
           <td> 
           <input id='password' type='password' name='pwd' placeholder='Password' onkeyup="checkComplete('signup');" /> 
           </td> 
          </tr> 
          <tr> 
           <td colspan='2' style='text-align: center;'> 
           <button type='button' id='signupbtn' class='popbtn' disabled='disabled'>SIGN UP</button> 
           </td> 
          </tr> 
          </table> 
         </form> 
    

    因此,CSS可能混淆了一点,但基本形式如下:

    <form id='signupform' enctype="multipart/form-data"> 
        <input id='fname' type='text' name='first' /> 
        <input id='lname' type='text' name='last' /> 
        <input id='usrimg' type='file' name='userimage' /> 
        <input id='username' type='text' name='uid' /> 
        <input id='password' type='password' name='pwd' /> 
        <button type='button' id='signupbtn'>SIGN UP</button> 
    </form> 
    

    所以signupbtn按钮具有附着在文档加载一个onclick事件(也是在index.php文件,我没有展示这一切,因为它是不适合此):

    $(function() { 
         $('#signupbtn').click(function(e) { 
         e.preventDefault(); 
         e.stopImmediatePropagation(); 
    
         $.ajax({ 
          type: "POST", 
          url: "signup.php", 
          data: $('#signupform').serialize(), 
          success: function(response){ 
          //... 
          } 
         }); 
         return false; 
         }); 
    
        //... 
    
    }); 
    

    所以我用AJAX调用文件signup.php提交表单不清爽。然后在该文件:

    <?php 
        session_start(); 
    
        include('connect.php'); 
    
        $first = $_POST['first']; 
        $last = $_POST['last']; 
        $img = mysqli_real_escape_string(file_get_contents($_FILES['userimage']['tmp_name'])); 
        $uid = $_POST['uid']; 
        $pwd = $_POST['pwd']; 
    
        $query = "insert into Users (first, last, img, uid, pwd) values (?,?,?,?,?)"; 
        $stmt = mysqli_prepare($connect, $query); 
        mysqli_stmt_bind_param($stmt, 'ssbss', $first, $last, $img, $uid, $pwd); 
        mysqli_stmt_send_long_data($stmt, 2, $img); 
        $res = mysqli_stmt_execute($stmt); 
    
        echo $res; 
    ?> 
    

    我检索所有表单中的信息,然后使用mysqli_stmt_send_long_data在插入我的形象成表,这是在connect.php创建尝试:

    <?php 
        $host_name = "xxx"; 
        $database = "xxx"; 
        $user_name = "xxx"; 
        $password = "xxx"; 
    
    
        $connect = mysqli_connect($host_name, $user_name, $password, $database); 
    
        if(mysqli_connect_errno()) { 
        echo '<p>Failed to connect to MySQL: '.mysqli_connect_error().'</p>'; 
        } 
        else { 
        //echo '<p>Connection to MySQL server successfully established.</p>'; 
        $db_selected = mysqli_select_db($connect, $database); 
    
        if ($db_selected) { 
         $userTableName = 'Users'; 
    
         $userTableExists = mysqli_query($connect, "select * from $userTableName"); 
         if (!$userTableExists) { 
         echo 'The table ' . $userTableName . ' does not exist. Creating...<br /><br />'; 
    
         $sqlCreateTable = "create table " . $userTableName . "(id int(11) not null PRIMARY KEY AUTO_INCREMENT, 
                       first varchar(128) not null, 
                       last varchar(128) not null, 
                       img longblob not null, 
                       uid varchar(128) not null, 
                       pwd varchar(1000) not null)"; 
         $result = mysqli_query($connect, $sqlCreateTable); 
    
         if ($result) { 
            echo 'Table ' . $userTableName . ' created...<br>'; 
           } 
           else { 
            die("Cannot create table " . $userTableName . ": " . mysql_error()); 
           } 
         } 
        } 
        else { 
          die("Cannot use " . $database . ": " . mysql_error()); 
         } 
        } 
    ?> 
    

    由于你会期望,因为我问这个问题,Ajax成功结束,并插入行。但是,当我检查phpMyAdmin的在我的网站的数据库中,我得到了img领域具有[BLOB - 0 B]值这只能意味着图片上传不工作。可能是什么情况?我在send_long_data上找不到任何工作,但也许有人遇到了同样的问题。提前感谢您提供任何答案。

    +1

    **永不**存储纯文本密码。你应该使用['password_hash()'](http://us3.php.net/manual/en/function.password-hash.php)和['password_verify()'](http://us3.php。 net/manual/en/function.password-verify.php)。如果您使用的是5.5之前的PHP版本,请不要**使用MD5或SHA1来散列密码。相反,您可以使用[此兼容包](https://github.com/ircmaxell/password_compat)。 –

    +1

    列的字段类型是什么? –

    +0

    @Alex Howansky是的,我明白了。这不会是我的最终版本。如果可以的话,我想学习如何加密密码等,但是我开始进行图像插入并卡在这里! – gfcf14

    回答

    0

    Jay Blanchard的建议后,我决定放弃BLOB的想法,而是保存关于图像的字符串信息。对于这一点,我第一次修改的connect.php文件创建一个更好的版本表:

    <?php 
        $host_name = "xxx"; 
        $database = "xxx"; 
        $user_name = "xxx"; 
        $password = "xxx"; 
    
    
        $connect = mysqli_connect($host_name, $user_name, $password, $database); 
    
        if(mysqli_connect_errno()) { 
        echo '<p>Failed to connect to MySQL: '.mysqli_connect_error().'</p>'; 
        } 
        else { 
        //echo '<p>Connection to MySQL server successfully established.</p>'; 
        $db_selected = mysqli_select_db($connect, $database); 
    
        if ($db_selected) { 
         $userTableName = 'Users'; 
    
         $userTableExists = mysqli_query($connect, "select * from $userTableName"); 
         if (!$userTableExists) { 
         echo 'The table ' . $userTableName . ' does not exist. Creating...<br /><br />'; 
    
         $sqlCreateTable = "create table " . $userTableName . "(id int(11) not null PRIMARY KEY AUTO_INCREMENT, 
                       first varchar(128) not null, 
                       last varchar(128) not null, 
                       sex varchar(1) not null, 
                       img varchar(5) not null, 
                       uid varchar(128) not null, 
                       pwd varchar(1000) not null)"; 
         $result = mysqli_query($connect, $sqlCreateTable); 
    
         if ($result) { 
            echo 'Table ' . $userTableName . ' created...<br>'; 
           } 
           else { 
            die("Cannot create table " . $userTableName . ": " . mysql_error()); 
           } 
         } 
        } 
        else { 
          die("Cannot use " . $database . ": " . mysql_error()); 
         } 
        } 
    ?> 
    

    所以,现在有两个新领域:性(1个字符,以节省是“M”或“F”),和img(最多5个字符来保存图像EXTENSION)。让这一点非常重要的是,为了让这个表单感觉更完整,用户应该有机会选择他们自己的图像,或者选择一个临时的默认图像。这就是为什么性别领域是重要的,什么反映形式的变化:

    <form id='signupform' enctype="multipart/form-data"> 
        <input id='fname' type='text' name='first' /> 
        <input id='lname' type='text' name='last' /> 
        I am <input type='radio' name='sex' value='m' />Male <input type='radio' name='sex' value='f' />Female 
        <input id='usrimg' type='file' name='userimage' /> 
        <input type='checkbox' id='imgdef' />Use a default image for now 
        <input id='username' type='text' name='uid' /> 
        <input id='password' type='password' name='pwd' /> 
        <button type='button' id='signupbtn'>SIGN UP</button> 
    </form> 
    

    所以现在,当我按下signupbtn,二AJAX函数调用,这取决于是否选中该复选框:

    $(function() { 
         $('#signupbtn').click(function(e) { 
         e.preventDefault(); 
         e.stopImmediatePropagation(); 
    
         var filextension; 
    
         if (!(document.getElementById('imgdef').checked)) { 
          filextension = $('#usrimg').val().substr($('#usrimg').val().lastIndexOf('.') + 1); 
    
          var fdata = new FormData(); 
          fdata.append('first', $('#fname').val()); 
          fdata.append('last', $('#lname').val()); 
          fdata.append('sex', $("#signupform input[type='radio']:checked").val()); 
          fdata.append('userimage', $('#usrimg').prop("files")[0]); 
          fdata.append('uid', $('#username').val()); 
          fdata.append('pwd', $('#password').val()); 
          fdata.append('filextension', filextension); 
    
          $.ajax({ 
          type: "POST", 
          url: "uploadimage.php", 
          data: fdata, 
          processData: false, 
          contentType: false 
          }); 
         } 
         else filextension = 'no'; 
    
         $.ajax({ 
          type: "POST", 
          url: "signup.php", 
          data: $('#signupform').serialize() + '&filextension=' + filextension, 
          success: function(response) { 
          //... 
          } 
         }); 
         }); 
    
         //... 
    }); 
    

    如果没有选中该复选框,则用户上传自己的形象。在这种情况下,我做一个FORMDATA下AJAX正确上传(注:我失去的时候一个很好的协议分配signupform作为参数,该文件将永远不会上传这样),那么当一切都被追加,我称之为AJAX功能,将调用uploadimage.php

    <?php 
        include('connect.php'); 
    
        $res = mysqli_query($connect, "select count(1) from Users"); 
        $row = mysqli_fetch_array($res); 
        $imgnum = $row[0]; 
    
        $dir = 'Users/'; 
        $ext = $_POST['filextension']; 
        $file = $dir . 'user' . $imgnum . '.' . $ext; 
    
        $upload = move_uploaded_file($_FILES['userimage']['tmp_name'], $file); 
    ?> 
    

    的代码更简单似乎比。虽然总是建议检查该文件是否为图像,如果大小是正确的,那么我已经在javascript中这样做了,所以我甚至不打扰到这里。在这里,我得到Users表的行数,以便我可以得到下一个用户。我这样做是因为我发现使用通用名称保存上传图像更方便(在这种情况下,根据表中是否有n行,新用户的图像将被保存为usern.ext,其中ext将是扩展名(jpg ,PNG,GIF等)),而不必保留原始图像名称的整个字符串。

    在用户选择默认的情况下,该分机变成no以在其显示器上指示。基本上,在index.php另一种形式被用于登录,提供用户名和密码,名为signin.php文件:

    <?php 
        session_start(); 
    
        include('connect.php'); 
    
        $uid = $_POST['signinuid']; 
        $pwd = $_POST['signinpwd']; 
    
        $sql = "select * from Users where uid='$uid' and pwd='$pwd'"; 
        $res = mysqli_query($connect, $sql); 
    
        $row = mysqli_fetch_assoc($res); 
    
        $_SESSION['id'] = $row['id']; 
        $_SESSION['first'] = $row['first']; 
        $_SESSION['last'] = $row['last']; 
        $_SESSION['sex'] = $row['sex']; 
        $_SESSION['img'] = $row['img']; 
        $_SESSION['uid'] = $row['uid']; 
    
        header("Location: http://....php"); 
    ?> 
    

    所以当所有这些值的用户日志存储在$ _SESSION,然后页面刷新。这是这样,如果一个用户登录,他们的信息可以证明,而不是提示注册或登录(其中被隐藏),用登出按钮一起:

    <?php 
         if ($_SESSION['id']) { 
         $soutid = 'signout'; 
         echo "<table style='margin: 0px auto;'>"; 
          echo "<tr>"; 
          echo "<td colspan='2'>"; 
           echo "<h1>WELCOME!</h1>"; 
          echo "</td>"; 
          echo "</tr>"; 
          echo "<tr>"; 
          echo "<td>"; 
           if ($_SESSION['img'] == 'no') { 
           echo "<img src='Users/" . $_SESSION['sex'] . "def.png' alt=''>"; 
           } 
           else echo "<img src='Users/user" . $_SESSION['id'] . "." . $_SESSION['img'] . "' alt=''>"; 
          echo "</td>"; 
          echo "<td>"; 
           echo "<div style='color: #007146; font-size: 20px; text-align: center;'>"; 
           echo $_SESSION['first'] . " " . $_SESSION['last'] . "(" . $_SESSION['uid'] . ")"; 
           echo "</div>"; 
          echo "</td>"; 
          echo "</tr>"; 
          echo "<tr>"; 
          echo "<td colspan='2'>"; 
           echo "<form id='$soutid' method='POST' action='signout.php'>"; 
           echo "<button type='button' class='popbtn'>Sign Out</a>"; 
           echo "</form>"; 
          echo "</td>"; 
          echo "</tr>"; 
         echo "</table>"; 
         } 
        ?> 
    

    这是我所有的心计走到一起,如果$_SESSION['img']no的,然后我调用默认的图像,mdef.pngfdef.png,这取决于用户选择在签署后,这一行:

    echo "<img src='Users/" . $_SESSION['sex'] . "def.png' alt=''>"; 
    

    而且,如果用户提供一张图片,我用它们的ID和存储的扩展名称:

    echo "<img src='Users/user" . $_SESSION['id'] . "." . $_SESSION['img'] . "' alt=''>"; 
    

    我没有显示我的所有代码,因为我想先完成我的表单。我还没有对密码,确认电子邮件,密码恢复和用户个人资料页面进行散列处理(既可以查看未登录的用户,也可以查看用户的编辑状态)。一旦我完成了这个,我会记录我的进度,并在这里留下一个视频链接。感谢所有帮助我达到这个状态的人。

    最后编辑:该项目已经完成!你会在这里找到一个演示视频:https://www.youtube.com/watch?v=cLpbKdTY_xo&t=2s

    相关问题