2017-04-26 3 views
0

Ich bin ein Logging-System zu schaffen, für die ich den Benutzer wünschen, zusammen mit grundlegenden Informationen (Name, Benutzername, Passwort) sein Profil Bild zu speichern. Dazu habe ich diese Dateien kodiert:PHP - Kein Bild über mysqli_stmt_send_long_data senden

Das HTML-Formular (bei 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> 

So kann die CSS ein wenig verwirren, aber im Grunde die Form ist wie folgt:

<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> 

so ist die signupbtn Taste hat eine onclick Ereignis auf Dokument Last befestigt (auch bei index.php, zeige ich es nicht alles, wie es nicht relevant für diese ist):

$(function() { 
     $('#signupbtn').click(function(e) { 
     e.preventDefault(); 
     e.stopImmediatePropagation(); 

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

    //... 

}); 
So

Ich benutze Ajax um die Datei zu nennen signup.php das Formular ohne erfrischend zu unterbreiten. Dann auf diese Datei:

<?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; 
?> 

ich alle Informationen aus dem Formular abrufen, dann mysqli_stmt_send_long_data verwenden, um das Einfügen mein Bild in die Tabelle, um zu versuchen, die auf connect.php erstellt:

<?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()); 
     } 
    } 
?> 

Wie du würdest erwarten, da ich die Frage stelle, endet der Ajax mit Erfolg und die Zeile wird eingefügt. Aber während ich phpMyAdmin in der Datenbank meiner Site überprüfe, bekomme ich, dass das img Feld einen Wert von [BLOB - 0 B] hat, was nur bedeuten kann, dass das Hochladen des Bildes nicht funktioniert. Was könnte der Fall sein? Ich habe sehr wenig gefunden auf send_long_data funktioniert nicht, aber vielleicht hat jemand das gleiche Problem gehabt. Vielen Dank für die Antworten im Voraus.

+1

** Nie ** speichern Klartext Passwörter. Sie sollten ['password_hash()'] (http://us3.php.net/manual/en/function.password-hash.php) und ['password_verify()'] (http: //us3.php) verwenden. net/manual/de/function.password-verify.php) statt. Wenn Sie eine Version von PHP vor Version 5.5 verwenden, verwenden Sie ** nicht ** MD5 oder SHA1, um Passwörter zu hashen. Stattdessen können Sie [dieses Kompatibilitätspaket] (https://github.com/ircmaxell/password_compat) verwenden. –

+1

Was ist der Feldtyp der Spalte? –

+0

@Alex Howansky Ja, ich komme dazu. Dies wird nicht meine endgültige Version sein. Wenn ich kann, möchte ich lernen, das Passwort und so zu salzen, aber ich fing an, das Bild einzufügen und steckte hier fest! – gfcf14

Antwort

0

Nach Vorschlag von Jay Blanchard habe ich beschlossen, die BLOB Idee zu verwerfen und stattdessen String Informationen über die Bilder zu speichern. Dazu habe ich geändert zuerst die connect.php Datei eine bessere Version der Tabelle zu erstellen:

<?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()); 
     } 
    } 
?> 

dort So, jetzt sind zwei neue Felder: Sex (1 Zeichen entweder ‚m‘ oder ‚f‘ speichern), und img (bis zu 5 Zeichen zum Speichern der Bildvergrößerung). Was dies wichtig macht, ist, dass ein Benutzer die Möglichkeit haben sollte, ein eigenes Bild zu wählen oder sich für ein temporäres Standardbild zu entscheiden, um zu versuchen, dieses Formular vollständiger zu machen. Aus diesem Grund ist das Geschlecht Feld wichtig ist und was spiegelt die Veränderungen in der Form:

<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> 

So, jetzt, wenn ich drücken Sie die signupbtn, zwei Ajax-Funktionen in genannt werden, je nachdem, ob oder nicht das Kontrollkästchen aktiviert ist:

$(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) { 
      //... 
      } 
     }); 
     }); 

     //... 
}); 

Wenn das Kontrollkästchen nicht aktiviert ist, muss der Benutzer ein eigenes Bild hochladen. In diesem Fall mache ich eine Formdata für die richtige Upload unter Ajax (. Hinweis: Ich habe viel Zeit Zuweisen der signupform als Parameter verloren Die Datei wird nie auf diese Weise laden), dann, wenn alles angehängt wurde, nenne ich die ajax-Funktion, die uploadimage.php nennen:

<?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); 
?> 

Der Code ist einfacher als es scheint. Während es immer empfohlen wird, um zu überprüfen, ob die Datei ein Bild ist, wenn die Größe korrekt ist, und so mache ich das bereits in Javascript, also habe ich nicht einmal hier gestört.Hier bekomme ich die Anzahl der Zeilen der Users Tabelle, damit ich herausfinden kann, welcher Benutzer der nächste sein wird. Ich tue dies, weil es für mich bequemer ist, die hochgeladenen Bilder mit generischen Namen zu speichern (in diesem Fall würde das Bild des neuen Benutzers, je nachdem, ob es n Zeilen in der Tabelle gibt, als usern.ext gespeichert, wobei ext die Erweiterung (jpg , png, gif usw.)), anstatt die ganze Zeichenfolge des ursprünglichen Bildnamens zu behalten.

Wenn der Benutzer sich für einen Standard entscheidet, wird die Erweiterung zu einem no, um auf seiner Anzeige anzuzeigen. Grundsätzlich gibt es eine andere Form in index.php, die sich einloggen verwendet wird, Benutzername und Passwort bereitstellt, in eine Datei signin.php genannt:

<?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"); 
?> 

Also, wenn sich der Benutzer anmeldet, alle diese Werte gespeichert werden in $ _SESSION, dann Die Seite wird aktualisiert. Dies ist so, dass, wenn ein Benutzer angemeldet ist, ihre Informationen angezeigt werden können, statt Aufforderung zur Anmeldung oder loggen Sie sich ein (die versteckt wird), zusammen mit einem Schild aus Taste:

<?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>"; 
     } 
    ?> 

Hier wie alle meine intrigante kommt zusammen, wenn $_SESSION['img']no ist, dann rufe ich die Standardbilder, mdef.png und fdef.png, je nachdem, was der Benutzer wählen bei der Anmeldung, mit dieser Zeile:

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

und wenn der Benutzer zur Verfügung gestellt ein Bild, ich rufe es mit ihrer ID und der Erweiterung, die gespeichert wurde:

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

Ich zeige nicht alle meinen Code, weil ich zuerst mein Formular ausfüllen möchte. Ich habe nicht daran gearbeitet, das Kennwort, die Bestätigungs-E-Mail, die Passwortwiederherstellung und die Benutzerprofilseiten zu hashen (um einen nicht angemeldeten Benutzer zu sehen und um zu sehen, dass der Benutzer nach Belieben bearbeiten kann). Sobald ich damit fertig bin, werde ich meine Fortschritte aufzeichnen und einen Link zu einem Video hier hinterlassen. Danke an alle, die mir in diesen Zustand geholfen haben.

LETZTE BEARBEITUNG: Das Projekt ist jetzt fertig! Hier finden Sie ein Demo-Video: https://www.youtube.com/watch?v=cLpbKdTY_xo&t=2s